diff --git a/DEPS b/DEPS
index d8ae335d..65fbd96 100644
--- a/DEPS
+++ b/DEPS
@@ -315,15 +315,15 @@
   # 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': '94b451811838c540f8ef682ad7da45c6ccf0b450',
+  'angle_revision': '8e644365328cf908e0c4de02707c58322228b589',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
-  'swiftshader_revision': '440133b5d4062caa97de0b005fd695581a41a4bc',
+  'swiftshader_revision': 'ab3cb3f5416b4363f4d4f0e06b35ec8c3dc4714c',
   # 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': '9d2c662f557544e5edb74a60b52fb297f4c5dfee',
+  'pdfium_revision': 'df597389f17570984deab15fd9272a49e0865b02',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
@@ -378,7 +378,7 @@
   # 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': 'db91f6cd331aba553d84f25240d2df465fd88a62',
+  'catapult_revision': 'df8440aca35dcbdaf56ecc3a5ded229fedf80cc7',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -386,7 +386,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': '33bb29b551b54b0ac67025e8b3e0ce69352c9504',
+  'devtools_frontend_revision': '885a1efecc4f0569e3591039698c6a4871cd186f',
   # 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.
@@ -422,11 +422,11 @@
   # 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': 'c84d06e8603ce9c4b5c8d86e42e9ec0acf3bd689',
+  'dawn_revision': 'ec7ba9f1f853ffa1c79c1e3302803c49b0e34568',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'quiche_revision': 'a338ea8277642f6d78022dc8e3aaed182a804413',
+  'quiche_revision': '44da7b642b96fabf8af3eeda44210ae92290cc00',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ios_webkit
   # and whatever else without interference from each other.
@@ -689,7 +689,7 @@
       'packages': [
         {
           'package': 'chromium/third_party/updater/chrome_win_x86',
-          'version': 'rqP-urpwa5NOuHhuLVNHyT9d_Psk1xDc8ELSstaIkUUC',
+          'version': '_YCMx6KK9JLuRq3i2A1hNXPeWPs3xx7DU9pKGBHaY9MC',
         },
       ],
   },
@@ -700,7 +700,7 @@
       'packages': [
         {
           'package': 'chromium/third_party/updater/chrome_win_x86_64',
-          'version': '7nSN9jjsZ507lwEcJQKUFM_Z2wHmjJmU3nzo1s-r8-UC',
+          'version': 'B219feMqLtKlWnB8ll-PE7Dyk9odtx1_hMshE5e6lWgC',
         },
       ],
   },
@@ -735,7 +735,7 @@
       'packages': [
         {
           'package': 'chromium/third_party/updater/chromium_win_x86',
-          'version': '2yELAOdPaRyB3HuFsiecHXc4zcXVupx9cLa9ZAh-Z2wC',
+          'version': 'IC4eBusb77p8RW3eBAhJ2LQzPffPuV6lqwqm7NwxNSkC',
         },
       ],
   },
@@ -746,7 +746,7 @@
       'packages': [
         {
           'package': 'chromium/third_party/updater/chromium_win_x86_64',
-          'version': 'vuc_q-ghg3H11b1O-ENURYlDO8hrcpCc4AuN1Expx3gC',
+          'version': 'Ea-jhu4lipIfpqmOJBH1nfruzXa0ETDXcjHa7NP-5PcC',
         },
       ],
   },
@@ -818,7 +818,7 @@
 
   'src/clank': {
     'url': 'https://chrome-internal.googlesource.com/clank/internal/apps.git' + '@' +
-    'd71ee488b3dfc34f836410eaace4f52915ad7872',
+    'a0e04a26b39321d968a46481f018e2a9a35e060e',
     'condition': 'checkout_android and checkout_src_internal and not checkout_clank_via_src_internal',
   },
 
@@ -842,7 +842,7 @@
   },
 
   'src/ios/third_party/material_components_ios/src': {
-      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '416a8ce75bcf827e8e99825aac8b4b7c5857fa5b',
+      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'b09e2076adb89f84e4066f95dd5550765668b018',
       'condition': 'checkout_ios',
   },
 
@@ -1002,7 +1002,7 @@
     'packages': [
       {
           'package': 'chromium/third_party/androidx',
-          'version': '0MVUzH0ad0hBu4MqH3dIKpof2FXNYwequV_wMG4ijcoC',
+          'version': 'QqLBQB-SlihOduiRFlkYHR8gHZUk4disogVO5G8Zr18C',
       },
     ],
     'condition': 'checkout_android',
@@ -1251,7 +1251,7 @@
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
 
   'src/third_party/devtools-frontend-internal': {
-      'url': 'https://chrome-internal.googlesource.com/devtools/devtools-internal.git' + '@' + '4ac9d827b064e9b1847d2cec90ccb954198472d8',
+      'url': 'https://chrome-internal.googlesource.com/devtools/devtools-internal.git' + '@' + '5d28a6974d2af465a6b8bf36949cd4dcbf41558e',
     'condition': 'checkout_src_internal',
   },
 
@@ -1666,7 +1666,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '280f0b23c5c8b98248cf0ccf3d011c4fd4bb74f5',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '84e4d914dfccb1d76bf83d9d55e9fd68502e5076',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1811,7 +1811,7 @@
       'dep_type': 'cipd',
   },
 
-  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@f310d85385dfddbe1deeb05deda1045593225710',
+  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@2eb0a986e4f50b40c1fa1724564bc826c51a295b',
 
   'src/third_party/vulkan_memory_allocator':
     Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + 'ebe84bec02c041d28f902da0214bf442743fc907',
@@ -1848,10 +1848,10 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'd1b65aa5a88f6efd900604dfcda840154e9f16e2',
 
   'src/third_party/webgpu-cts/src':
-    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '9c402f750efed2504482b9ac8f075c2907e4ca1e',
+    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '9ff9ec53c07190a7add65392239939961a064da5',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + 'fb3bd4a01d7c840dfe7b3efa144c0fbcb6a97fef',
+    Var('webrtc_git') + '/src.git' + '@' + '2b5923c3d07ecce1c7995108a70e682f3f77bc39',
 
   # 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.
@@ -1921,7 +1921,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@73f9ffba35357a86d519287005b767c26e56f004',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@257b5837cf6a04c1ecbe9adab1b031154699a79c',
     'condition': 'checkout_src_internal',
   },
 
@@ -1973,7 +1973,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/projector_app/app',
-        'version': 'TaHxBUmYiVurXIHHo8Y5mOh7-SEnHbSCW7fn60_Wm54C',
+        'version': 'B7ZmuFDDM9VY1xvDM5U0hf4lHPfBxlK0SfaWQ2v1eWEC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/WATCHLISTS b/WATCHLISTS
index 1a36808..865e914 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -1433,7 +1433,7 @@
                   '|chrome/browser/ash/secure_channel/'\
                   '|chrome/browser/resources/chromeos/multidevice_setup/'\
                   '|chrome/browser/resources/settings/chromeos/multidevice_page/'\
-                  '|chrome/browser/ui/webui/chromeos/multidevice_setup/'\
+                  '|chrome/browser/ui/webui/ash/multidevice_setup/'\
                   '|chrome/browser/ui/webui/settings/ash/multidevice'\
                   '|chrome/test/data/webui/multidevice_setup/'\
                   '|chromeos/ash/components/multidevice/'\
@@ -2248,7 +2248,7 @@
     'android_studio': ['wnwen+watch@chromium.org',
                        'nyquist+watch@chromium.org'],
     'android_tab': ['dtrainor+watch@chromium.org'],
-    'android_toolbar': ['hanxi+watch@chromium.org', 'spdonghao+watch@chromium.org'],
+    'android_toolbar': ['hanxi+watch@chromium.org'],
     'android_toolbar_deps': ['jinsukkim+watch@chromium.org'],
     'android_uma_settings': ['asvitkine+watch@chromium.org',
                              'gayane+watch@chromium.org'],
@@ -2983,8 +2983,7 @@
                                  'gogerald+watch@chromium.org',
                                  'hanxi+watch@chromium.org',
                                  'mattsimmons+watch@chromium.org',
-                                 'davidjm+watch@chromium.org',
-                                 'spdonghao+watch@chromium.org'],
+                                 'davidjm+watch@chromium.org'],
     'tabs': ['mickeyburks+watch@chromium.org'],
     'tbmv2_metrics': ['speed-metrics-reviews@chromium.org'],
     'telemetry': ['telemetry-reviews@chromium.org'],
diff --git a/android_webview/browser/gfx/BUILD.gn b/android_webview/browser/gfx/BUILD.gn
index 77e4639b..7345eb38 100644
--- a/android_webview/browser/gfx/BUILD.gn
+++ b/android_webview/browser/gfx/BUILD.gn
@@ -81,7 +81,6 @@
     "//content/public/browser",
     "//gpu/command_buffer/client:gles2_implementation",
     "//gpu/command_buffer/service",
-    "//gpu/ipc/common:android_image_reader_utils",
     "//gpu/ipc/common:common",
     "//gpu/skia_bindings",
     "//gpu/vulkan:vulkan",
diff --git a/android_webview/browser/gfx/vulkan_gl_interop.cc b/android_webview/browser/gfx/vulkan_gl_interop.cc
index 426af84c..7913dd9 100644
--- a/android_webview/browser/gfx/vulkan_gl_interop.cc
+++ b/android_webview/browser/gfx/vulkan_gl_interop.cc
@@ -11,7 +11,6 @@
 #include "base/android/scoped_hardware_buffer_fence_sync.h"
 #include "gpu/command_buffer/service/ahardwarebuffer_utils.h"
 #include "gpu/command_buffer/service/skia_utils.h"
-#include "gpu/ipc/common/android/android_image_reader_utils.h"
 #include "gpu/vulkan/vulkan_fence_helper.h"
 #include "gpu/vulkan/vulkan_function_pointers.h"
 #include "gpu/vulkan/vulkan_image.h"
@@ -23,6 +22,7 @@
 #include "third_party/skia/include/gpu/vk/GrVkExtensions.h"
 #include "third_party/skia/src/gpu/vk/GrVkSecondaryCBDrawContext.h"
 #include "ui/gfx/gpu_memory_buffer.h"
+#include "ui/gl/android/egl_fence_utils.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_context_egl.h"
 #include "ui/gl/gl_surface_egl.h"
@@ -248,7 +248,7 @@
   }
 
   // Ask GL to wait on any Vk sync_fd before writing.
-  gpu::InsertEglFenceAndWait(std::move(pending_draw->sync_fd));
+  gl::InsertEglFenceAndWait(std::move(pending_draw->sync_fd));
 
   // Bind buffer and render with GL.
   base::ScopedFD gl_done_fd;
@@ -261,7 +261,7 @@
     glClear(GL_COLOR_BUFFER_BIT);
     render_thread_manager_->DrawOnRT(/*save_restore=*/false, params,
                                      overlays_params);
-    gl_done_fd = gpu::CreateEglFenceAndExportFd();
+    gl_done_fd = gl::CreateEglFenceAndExportFd();
   }
 
   pending_draw->draw_context = std::move(draw_context);
diff --git a/ash/capture_mode/capture_mode_feature_pod_controller.cc b/ash/capture_mode/capture_mode_feature_pod_controller.cc
index f5c12b8..b59efe22 100644
--- a/ash/capture_mode/capture_mode_feature_pod_controller.cc
+++ b/ash/capture_mode/capture_mode_feature_pod_controller.cc
@@ -35,6 +35,7 @@
   button_->SetLabelTooltip(label_text);
   button_->SetVisible(
       !Shell::Get()->session_controller()->IsUserSessionBlocked());
+  button_->DisableLabelButtonFocus();
   return button_;
 }
 
diff --git a/ash/clipboard/views/clipboard_history_item_view.cc b/ash/clipboard/views/clipboard_history_item_view.cc
index f51ae3d..085ac69 100644
--- a/ash/clipboard/views/clipboard_history_item_view.cc
+++ b/ash/clipboard/views/clipboard_history_item_view.cc
@@ -270,7 +270,7 @@
   // A valid role must be set in the AXNodeData prior to setting the name
   // via AXNodeData::SetName.
   data->role = ax::mojom::Role::kMenuItem;
-  data->SetName(GetAccessibleName());
+  data->SetNameChecked(GetAccessibleName());
 }
 
 void ClipboardHistoryItemView::Activate(Action action, int event_flags) {
diff --git a/ash/components/arc/compat_mode/touch_mode_mouse_rewriter.cc b/ash/components/arc/compat_mode/touch_mode_mouse_rewriter.cc
index 7e766ce..15aef79b 100644
--- a/ash/components/arc/compat_mode/touch_mode_mouse_rewriter.cc
+++ b/ash/components/arc/compat_mode/touch_mode_mouse_rewriter.cc
@@ -173,7 +173,7 @@
   scroll_y_offset_ += kWheelToSmoothScrollScale * event.y_offset();
   scroll_x_offset_ += kWheelToSmoothScrollScale * event.x_offset();
   scroll_timeout_ = kSmoothScrollTimeout;
-  if (started) {
+  if (!started) {
     ui::ScrollEvent fling_cancel_event(
         ui::ET_SCROLL_FLING_CANCEL, event.location_f(), event.root_location_f(),
         event.time_stamp(), 0, 0, 0, 0, 0, 0);
diff --git a/ash/components/arc/compat_mode/touch_mode_mouse_rewriter_unittest.cc b/ash/components/arc/compat_mode/touch_mode_mouse_rewriter_unittest.cc
index 2a31871f..4b4d5c2 100644
--- a/ash/components/arc/compat_mode/touch_mode_mouse_rewriter_unittest.cc
+++ b/ash/components/arc/compat_mode/touch_mode_mouse_rewriter_unittest.cc
@@ -64,6 +64,7 @@
       smooth_scrolled_ = true;
       x_offset_ += event->x_offset();
       y_offset_ += event->y_offset();
+      scroll_timestamps.push_back(base::TimeTicks::Now());
     }
   }
 
@@ -72,6 +73,9 @@
   bool smooth_scrolled() const { return smooth_scrolled_; }
   int x_scroll_offset() { return x_offset_; }
   int y_scroll_offset() { return y_offset_; }
+  std::vector<base::TimeTicks> get_scroll_timestamps() {
+    return scroll_timestamps;
+  }
 
  private:
   bool fling_started_ = false;
@@ -79,6 +83,7 @@
   bool smooth_scrolled_ = false;
   int x_offset_ = 0;
   int y_offset_ = 0;
+  std::vector<base::TimeTicks> scroll_timestamps;
 };
 
 }  // namespace
@@ -398,4 +403,41 @@
   touch_mode_mouse_rewriter.DisableForWindow(widget->GetNativeWindow());
 }
 
+TEST_F(TouchModeMouseRewriterTest, VerticalWheelScrollCorrectInterval) {
+  std::unique_ptr<views::Widget> widget =
+      CreateTestWidget(views::Widget::InitParams::TYPE_CONTROL);
+  ScrollReceiverView* view =
+      widget->SetContentsView(std::make_unique<ScrollReceiverView>());
+  widget->Show();
+
+  TouchModeMouseRewriter touch_mode_mouse_rewriter;
+  touch_mode_mouse_rewriter.EnableForWindow(widget->GetNativeWindow());
+  ui::test::EventGenerator generator(GetContext(), widget->GetNativeWindow());
+
+  // Generate 3 scrolls at 5ms after another (0ms, 5ms, 10ms).
+  // The scroll event should still be sent at (0ms, 20ms, 40ms, ...),
+  // and not (0ms, 5ms, 10ms, 20ms, 25ms, 30ms).
+  // Interval is set at kSmoothScrollEventInterval.
+  generator.MoveMouseWheel(0, 10);
+  base::RunLoop().RunUntilIdle();
+  task_environment()->FastForwardBy(base::Milliseconds(5));
+  generator.MoveMouseWheel(0, 10);
+  base::RunLoop().RunUntilIdle();
+  task_environment()->FastForwardBy(base::Milliseconds(5));
+  generator.MoveMouseWheel(0, 10);
+  base::RunLoop().RunUntilIdle();
+
+  // Smooth scrolling ended.
+  task_environment()->FastForwardBy(base::Seconds(1));
+
+  std::vector<base::TimeTicks> timestamps = view->get_scroll_timestamps();
+  EXPECT_TRUE(!timestamps.empty());
+  for (size_t i = 1; i < timestamps.size(); i++) {
+    base::TimeDelta interval = timestamps[i] - timestamps[i - 1];
+    EXPECT_EQ(base::Milliseconds(20), interval);
+  }
+
+  touch_mode_mouse_rewriter.DisableForWindow(widget->GetNativeWindow());
+}
+
 }  // namespace arc
diff --git a/ash/constants/ash_pref_names.cc b/ash/constants/ash_pref_names.cc
index a5f61387..4b2c9d0 100644
--- a/ash/constants/ash_pref_names.cc
+++ b/ash/constants/ash_pref_names.cc
@@ -705,6 +705,10 @@
 // Boolean controlling whether quick dim is enabled.
 const char kPowerQuickDimEnabled[] = "power.quick_dim_enabled";
 
+// Quick lock delay is used inside powerd to control the delay time for a screen
+// lock to happen if the user is detected to be absent.
+const char kPowerQuickLockDelay[] = "power.quick_lock_delay.ms";
+
 // Boolean controlling whether the settings is enabled. This pref is intended to
 // be set only by policy not by user.
 const char kOsSettingsEnabled[] = "os_settings_enabled";
diff --git a/ash/constants/ash_pref_names.h b/ash/constants/ash_pref_names.h
index dd68bbc7..f487b8b 100644
--- a/ash/constants/ash_pref_names.h
+++ b/ash/constants/ash_pref_names.h
@@ -326,7 +326,7 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kPowerSmartDimEnabled[];
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kPowerAlsLoggingEnabled[];
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kPowerQuickDimEnabled[];
-
+COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kPowerQuickLockDelay[];
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kShelfAlignment[];
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kShelfAlignmentLocal[];
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kShelfAutoHideBehavior[];
diff --git a/ash/curtain/security_curtain_controller_impl.cc b/ash/curtain/security_curtain_controller_impl.cc
index ca7a8b3..170b5ea2 100644
--- a/ash/curtain/security_curtain_controller_impl.cc
+++ b/ash/curtain/security_curtain_controller_impl.cc
@@ -17,6 +17,7 @@
 void SecurityCurtainControllerImpl::Enable(InitParams params) {
   DCHECK_EQ(session_, nullptr);
   session_ = std::make_unique<Session>(&shell_, params);
+  session_->Init();
 }
 
 void SecurityCurtainControllerImpl::Disable() {
diff --git a/ash/curtain/security_curtain_controller_impl_unittest.cc b/ash/curtain/security_curtain_controller_impl_unittest.cc
index 8e22ba1..37978b03 100644
--- a/ash/curtain/security_curtain_controller_impl_unittest.cc
+++ b/ash/curtain/security_curtain_controller_impl_unittest.cc
@@ -2,14 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ash/curtain/security_curtain_controller_impl.h"
+#include "ash/curtain/security_curtain_controller.h"
 
 #include "ash/curtain/security_curtain_widget_controller.h"
+#include "ash/display/cursor_window_controller.h"
+#include "ash/display/window_tree_host_manager.h"
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/root_window_controller.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
-#include "base/callback_forward.h"
 #include "chromeos/ash/components/audio/cras_audio_handler.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -18,7 +19,7 @@
 #include "ui/views/widget/widget.h"
 
 namespace aura {
-// This improves the error output for our tests that compare OcclusionState.
+// This improves the error output for our tests that compare `OcclusionState`.
 std::ostream& operator<<(std::ostream& os, Window::OcclusionState state) {
   os << Window::OcclusionStateToString(state);
   return os;
@@ -53,7 +54,7 @@
   bool has_seen_event_ = false;
 };
 
-// Helper class that allows observing of all ui::Event's on a given target
+// Helper class that allows observing of all `ui::Event`'s on a given target
 // window, and which allows easy generation of input events.
 class EventTester {
  public:
@@ -88,25 +89,25 @@
       const SecurityCurtainControllerImplTest&) = delete;
   ~SecurityCurtainControllerImplTest() override = default;
 
-  void SetUp() override {
-    AshTestBase::SetUp();
-    security_curtain_controller_.emplace(ash::Shell::Get());
-  }
+  void SetUp() override { AshTestBase::SetUp(); }
 
-  void TearDown() override {
-    // SecurityCurtainController cannot outlive Ash::Shell();
-    security_curtain_controller_.reset();
-    AshTestBase::TearDown();
-  }
+  void TearDown() override { AshTestBase::TearDown(); }
 
   SecurityCurtainController& security_curtain_controller() {
-    return security_curtain_controller_.value();
+    return ash::Shell::Get()->security_curtain_controller();
   }
 
   SecurityCurtainController::InitParams init_params() {
     return SecurityCurtainController::InitParams();
   }
 
+  bool IsNativeCursorEnabled() {
+    return !Shell::Get()
+                ->window_tree_host_manager()
+                ->cursor_window_controller()
+                ->is_cursor_compositing_enabled();
+  }
+
   SecurityCurtainController::InitParams WithEventFilter(EventFilter filter) {
     return SecurityCurtainController::InitParams{filter};
   }
@@ -194,9 +195,6 @@
     return EventTester(CreateTestWindow(display.bounds()),
                        *GetEventGenerator());
   }
-
- private:
-  absl::optional<SecurityCurtainControllerImpl> security_curtain_controller_;
 };
 
 EventFilter only_mouse_events_filter() {
@@ -477,5 +475,22 @@
   EXPECT_FALSE(IsOutputMuted());
 }
 
+TEST_F(SecurityCurtainControllerImplTest,
+       ShouldDisableNativeMouseCursorWhenEnableIsCalled) {
+  ASSERT_THAT(IsNativeCursorEnabled(), Eq(true));
+
+  security_curtain_controller().Enable(init_params());
+
+  ASSERT_THAT(IsNativeCursorEnabled(), Eq(false));
+}
+
+TEST_F(SecurityCurtainControllerImplTest,
+       ShouldReenableNativeMouseCursorWhenDisableIsCalled) {
+  security_curtain_controller().Enable(init_params());
+  security_curtain_controller().Disable();
+
+  ASSERT_THAT(IsNativeCursorEnabled(), Eq(true));
+}
+
 }  // namespace
 }  // namespace ash::curtain
diff --git a/ash/curtain/session.cc b/ash/curtain/session.cc
index 0305fdc..c35ac48d 100644
--- a/ash/curtain/session.cc
+++ b/ash/curtain/session.cc
@@ -82,8 +82,25 @@
   CurtainOffAllRootWindows();
 }
 
+void Session::Init() {
+  // We must ensure we use a cursor drawn by the software, as a cursor drawn
+  // by the hardware will appear above our curtain which we do not want.
+  // So we tell the shell to tell the cursor manager to ask us if cursor
+  // compositing should be enabled.
+  // This then ends up calling `SecurityCurtainController::IsEnabled()` which is
+  // only true after our constructor is finished, so we must move this in a
+  // separate Init() method instead.
+  shell_->UpdateCursorCompositingEnabled();
+}
+
 Session::~Session() {
-  RemoveCurtainOfAllRootWindows();
+  // Skip all cleanup if the shell has been destroyed (so when Chrome is
+  // shutting down). This prevents us from using a half-destroyed `shell_`
+  // object.
+  if (ash::Shell::HasInstance()) {
+    RemoveCurtainOfAllRootWindows();
+    shell_->UpdateCursorCompositingEnabled();
+  }
 }
 
 void Session::CurtainOffAllRootWindows() {
diff --git a/ash/curtain/session.h b/ash/curtain/session.h
index 04e606a0..30fa160 100644
--- a/ash/curtain/session.h
+++ b/ash/curtain/session.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "ash/curtain/input_event_filter.h"
 #include "ash/curtain/security_curtain_controller.h"
 #include "base/memory/raw_ref.h"
 
@@ -34,6 +33,11 @@
   Session& operator=(const Session&) = delete;
   ~Session();
 
+  // Must be called after construction, and invokes code that calls
+  // `SecurityCurtainController::IsEnabled()` (which will only be true
+  // after the constructor of `Session` finishes).
+  void Init();
+
  private:
   void CurtainOffAllRootWindows();
   void CurtainOffRootWindow(aura::Window* root_window);
diff --git a/ash/display/cursor_window_controller.cc b/ash/display/cursor_window_controller.cc
index 4b01184c..80ce715 100644
--- a/ash/display/cursor_window_controller.cc
+++ b/ash/display/cursor_window_controller.cc
@@ -12,9 +12,8 @@
 #include "ash/constants/ash_constants.h"
 #include "ash/constants/ash_pref_names.h"
 #include "ash/constants/ash_switches.h"
+#include "ash/curtain/security_curtain_controller.h"
 #include "ash/display/display_color_manager.h"
-#include "ash/display/mirror_window_controller.h"
-#include "ash/display/window_tree_host_manager.h"
 #include "ash/fast_ink/cursor/cursor_view.h"
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/root_window_controller.h"
@@ -26,7 +25,6 @@
 #include "ui/aura/env.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_delegate.h"
-#include "ui/aura/window_event_dispatcher.h"
 #include "ui/base/hit_test.h"
 #include "ui/base/layout.h"
 #include "ui/base/resource/resource_bundle.h"
@@ -167,10 +165,14 @@
     return true;
   }
 
+  Shell* shell = Shell::Get();
+  if (shell->security_curtain_controller().IsEnabled()) {
+    return true;
+  }
+
   // During startup, we may not have a preference service yet. We need to check
   // display manager state first so that we don't accidentally ignore it while
   // early outing when there isn't a PrefService yet.
-  Shell* shell = Shell::Get();
   display::DisplayManager* display_manager = shell->display_manager();
   if ((display_manager->IsInSoftwareMirrorMode()) ||
       display_manager->IsInUnifiedMode() ||
diff --git a/ash/services/BUILD.gn b/ash/services/BUILD.gn
index 563bb9fc..ae7200c 100644
--- a/ash/services/BUILD.gn
+++ b/ash/services/BUILD.gn
@@ -17,8 +17,6 @@
   testonly = true
   deps = [
     "//ash/services/device_sync:unit_tests",
-    "//ash/services/ime:services_unittests",
-    "//ash/services/ime:unit_tests",
     "//ash/services/multidevice_setup:unit_tests",
     "//ash/services/secure_channel:unit_tests",
   ]
diff --git a/ash/system/power/power_prefs.cc b/ash/system/power/power_prefs.cc
index 694db1d..7d7a460 100644
--- a/ash/system/power/power_prefs.cc
+++ b/ash/system/power/power_prefs.cc
@@ -117,6 +117,8 @@
   registry->RegisterBooleanPref(prefs::kPowerSmartDimEnabled, true);
   registry->RegisterBooleanPref(prefs::kPowerAlsLoggingEnabled, false);
   registry->RegisterBooleanPref(prefs::kPowerQuickDimEnabled, false);
+  registry->RegisterIntegerPref(prefs::kPowerQuickLockDelay,
+                                hps::GetQuickLockDelay().InMilliseconds());
 
   registry->RegisterBooleanPref(prefs::kAllowScreenLock, true);
   registry->RegisterBooleanPref(
@@ -346,8 +348,9 @@
       values.ac_quick_dim_delay_ms = hps::GetQuickDimDelay().InMilliseconds();
 
       values.battery_quick_lock_delay_ms =
-          hps::GetQuickLockDelay().InMilliseconds();
-      values.ac_quick_lock_delay_ms = hps::GetQuickLockDelay().InMilliseconds();
+          prefs->GetInteger(prefs::kPowerQuickLockDelay);
+      values.ac_quick_lock_delay_ms =
+          prefs->GetInteger(prefs::kPowerQuickLockDelay);
 
       values.send_feedback_if_undimmed = hps::GetQuickDimFeedbackEnabled();
 
@@ -497,6 +500,7 @@
                           update_callback);
   profile_registrar_->Add(prefs::kPowerAlsLoggingEnabled, update_callback);
   profile_registrar_->Add(prefs::kPowerQuickDimEnabled, update_callback);
+  profile_registrar_->Add(prefs::kPowerQuickLockDelay, update_callback);
   profile_registrar_->Add(prefs::kPowerAdaptiveChargingEnabled,
                           update_callback);
 
diff --git a/ash/webui/os_feedback_ui/resources/search_page.js b/ash/webui/os_feedback_ui/resources/search_page.js
index 266ea7d8..7783fd6 100644
--- a/ash/webui/os_feedback_ui/resources/search_page.js
+++ b/ash/webui/os_feedback_ui/resources/search_page.js
@@ -153,6 +153,12 @@
      * @private {Array<string>}
      */
     this.appendedQuestions = [];
+
+    /**
+     * Whether the search result content is returned with popular content.
+     * @private {!boolean}
+     */
+    this.isPopularContentForTesting_;
   }
 
   ready() {
@@ -181,7 +187,8 @@
       this.hideError_();
     }
 
-    if (Math.abs(newCharCount - this.lastCharCount_) >= MIN_CHARS_COUNT) {
+    if (newCharCount == 0 ||
+        Math.abs(newCharCount - this.lastCharCount_) >= MIN_CHARS_COUNT) {
       this.lastCharCount_ = newCharCount;
       this.fetchHelpContent_(newInput);
     }
@@ -218,13 +225,16 @@
         response = await this.helpContentProvider_.getHelpContents(request);
         this.popularHelpContentList_ = response.response.results;
       }
+      this.helpContentSearchResultCount = this.popularHelpContentList_.length;
       isPopularContent = true;
     } else {
       response = await this.helpContentProvider_.getHelpContents(request);
       isPopularContent = (response.response.totalResults === 0);
+      this.helpContentSearchResultCount = response.response.results.length;
     }
 
     /** @type {!SearchResult} */
+    this.isPopularContentForTesting_ = isPopularContent;
     const data = {
       contentList: /** @type {!HelpContentList} */ (
           isPopularContent ? this.popularHelpContentList_ :
@@ -235,8 +245,6 @@
 
     this.noHelpContentDisplayed = (data.contentList.length === 0);
 
-    this.helpContentSearchResultCount = response.response.results.length;
-
     // Wait for the iframe to complete loading before postMessage.
     await this.iframeLoaded_;
     // TODO(xiangdongkong): Use Mojo to communicate with untrusted page.
@@ -366,6 +374,13 @@
   }
 
   /**
+   * @return {!boolean}
+   */
+  getIsPopularContentForTesting_() {
+    return this.isPopularContentForTesting_;
+  }
+
+  /**
    * Checks if any keywords have associated questionnaire in a domain. If so,
    * we append the questionnaire to the text input box.
    * @param inputEvent The input event for the description textarea.
diff --git a/base/memory/raw_ptr.h b/base/memory/raw_ptr.h
index 6028b49..c96a8143 100644
--- a/base/memory/raw_ptr.h
+++ b/base/memory/raw_ptr.h
@@ -19,6 +19,7 @@
 #include "base/allocator/partition_allocator/partition_alloc_base/debug/debugging_buildflags.h"
 #include "base/allocator/partition_allocator/partition_alloc_buildflags.h"
 #include "base/allocator/partition_allocator/partition_alloc_config.h"
+#include "base/base_export.h"
 #include "base/check.h"
 #include "build/build_config.h"
 #include "build/buildflag.h"
@@ -34,7 +35,6 @@
 #include "base/allocator/partition_allocator/address_pool_manager_bitmap.h"
 #include "base/allocator/partition_allocator/partition_address_space.h"
 #include "base/allocator/partition_allocator/partition_alloc_constants.h"
-#include "base/base_export.h"
 #endif  // BUILDFLAG(USE_BACKUP_REF_PTR) ||
         // defined(PA_ENABLE_MTE_CHECKED_PTR_SUPPORT_WITH_64_BITS_POINTERS)
 
diff --git a/base/profiler/libunwindstack_unwinder_android.cc b/base/profiler/libunwindstack_unwinder_android.cc
index 4d92d77..9be6624 100644
--- a/base/profiler/libunwindstack_unwinder_android.cc
+++ b/base/profiler/libunwindstack_unwinder_android.cc
@@ -85,7 +85,11 @@
 LibunwindstackUnwinderAndroid::LibunwindstackUnwinderAndroid()
     : memory_regions_map_(NativeUnwinderAndroid::CreateMaps()),
       process_memory_(std::shared_ptr<unwindstack::Memory>(
-          NativeUnwinderAndroid::CreateProcessMemory().release())) {}
+          NativeUnwinderAndroid::CreateProcessMemory().release())) {
+  TRACE_EVENT_INSTANT(
+      TRACE_DISABLED_BY_DEFAULT("cpu_profiler"),
+      "LibunwindstackUnwinderAndroid::LibunwindstackUnwinderAndroid");
+}
 
 LibunwindstackUnwinderAndroid::~LibunwindstackUnwinderAndroid() {
   if (module_cache()) {
diff --git a/build/android/pylib/local/device/local_device_environment.py b/build/android/pylib/local/device/local_device_environment.py
index bbb69da1..720aa9d 100644
--- a/build/android/pylib/local/device/local_device_environment.py
+++ b/build/android/pylib/local/device/local_device_environment.py
@@ -133,6 +133,7 @@
     self._trace_all = None
     if hasattr(args, 'trace_all'):
       self._trace_all = args.trace_all
+    self._use_persistent_shell = args.use_persistent_shell
 
     devil_chromium.Initialize(
         output_directory=constants.GetOutDirectory(),
@@ -172,7 +173,8 @@
         enable_device_files_cache=self._enable_device_cache,
         default_retries=self._max_tries - 1,
         device_arg=device_arg,
-        abis=self._preferred_abis)
+        abis=self._preferred_abis,
+        persistent_shell=self._use_persistent_shell)
 
     if self._logcat_output_file:
       self._logcat_output_dir = tempfile.mkdtemp()
diff --git a/build/android/test_runner.py b/build/android/test_runner.py
index 4e87be9..ff776fbd 100755
--- a/build/android/test_runner.py
+++ b/build/android/test_runner.py
@@ -315,6 +315,10 @@
       action='store_true',
       dest='upload_logcats_file',
       help='Whether to upload logcat file to logdog.')
+  parser.add_argument(
+      '--use-persistent-shell',
+      action='store_true',
+      help='Uses a persistent shell connection for the adb connection.')
 
   logcat_output_group = parser.add_mutually_exclusive_group()
   logcat_output_group.add_argument(
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1
index 1542969..e04d521 100644
--- a/build/fuchsia/linux_internal.sdk.sha1
+++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@
-10.20221013.1.1
+10.20221014.1.1
diff --git a/cc/layers/scrollbar_layer_unittest.cc b/cc/layers/scrollbar_layer_unittest.cc
index 6ef0a46..c1ef3c923 100644
--- a/cc/layers/scrollbar_layer_unittest.cc
+++ b/cc/layers/scrollbar_layer_unittest.cc
@@ -1423,7 +1423,7 @@
   // Keep the max texture size reasonable so we don't OOM on low end devices
   // (crbug.com/642333).
   context->UnboundTestContextGL()->set_max_texture_size(512);
-  context->BindToCurrentThread();
+  context->BindToCurrentSequence();
   int max_texture_size = 0;
   context->ContextGL()->GetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
   EXPECT_EQ(512, max_texture_size);
diff --git a/cc/paint/oop_pixeltest.cc b/cc/paint/oop_pixeltest.cc
index 627d802..9d724c8 100644
--- a/cc/paint/oop_pixeltest.cc
+++ b/cc/paint/oop_pixeltest.cc
@@ -114,7 +114,8 @@
         base::MakeRefCounted<viz::TestInProcessContextProvider>(
             viz::TestContextType::kGpuRaster, /*support_locking=*/true,
             &gr_shader_cache_, &activity_flags_);
-    gpu::ContextResult result = raster_context_provider_->BindToCurrentThread();
+    gpu::ContextResult result =
+        raster_context_provider_->BindToCurrentSequence();
     DCHECK_EQ(result, gpu::ContextResult::kSuccess);
     const int raster_max_texture_size =
         raster_context_provider_->ContextCapabilities().max_texture_size;
diff --git a/cc/paint/paint_op_buffer_fuzzer.cc b/cc/paint/paint_op_buffer_fuzzer.cc
index 05c01c8..44b6787 100644
--- a/cc/paint/paint_op_buffer_fuzzer.cc
+++ b/cc/paint/paint_op_buffer_fuzzer.cc
@@ -75,7 +75,7 @@
 
   SkImageInfo image_info = SkImageInfo::MakeN32(
       kRasterDimension, kRasterDimension, kOpaque_SkAlphaType);
-  context_provider->BindToCurrentThread();
+  context_provider->BindToCurrentSequence();
   sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(
       context_provider->GrContext(), SkBudgeted::kYes, image_info);
   SkCanvas* canvas = surface->getCanvas();
@@ -148,14 +148,14 @@
   }
 
   auto context_provider_no_support = viz::TestContextProvider::Create();
-  context_provider_no_support->BindToCurrentThread();
+  context_provider_no_support->BindToCurrentSequence();
   CHECK(!context_provider_no_support->GrContext()->supportsDistanceFieldText());
   Raster(context_provider_no_support, font_manager->strike_client(),
          &paint_cache, data, size);
 
   auto context_provider_with_support = viz::TestContextProvider::Create(
       std::string("GL_OES_standard_derivatives"));
-  context_provider_with_support->BindToCurrentThread();
+  context_provider_with_support->BindToCurrentSequence();
   CHECK(
       context_provider_with_support->GrContext()->supportsDistanceFieldText());
   Raster(context_provider_with_support, font_manager->strike_client(),
diff --git a/cc/paint/transfer_cache_fuzzer.cc b/cc/paint/transfer_cache_fuzzer.cc
index 45dbf7cb..28e9971 100644
--- a/cc/paint/transfer_cache_fuzzer.cc
+++ b/cc/paint/transfer_cache_fuzzer.cc
@@ -18,7 +18,7 @@
 
   scoped_refptr<viz::TestContextProvider> context_provider =
       viz::TestContextProvider::Create();
-  context_provider->BindToCurrentThread();
+  context_provider->BindToCurrentSequence();
 
   cc::TransferCacheEntryType entry_type =
       static_cast<cc::TransferCacheEntryType>(data[0]);
diff --git a/cc/raster/raster_buffer_provider_perftest.cc b/cc/raster/raster_buffer_provider_perftest.cc
index 6f18154..5a1cd48 100644
--- a/cc/raster/raster_buffer_provider_perftest.cc
+++ b/cc/raster/raster_buffer_provider_perftest.cc
@@ -95,7 +95,7 @@
     base::RefCountedThreadSafe<PerfContextProvider>::Release();
   }
 
-  gpu::ContextResult BindToCurrentThread() override {
+  gpu::ContextResult BindToCurrentSequence() override {
     return gpu::ContextResult::kSuccess;
   }
   const gpu::Capabilities& ContextCapabilities() const override {
diff --git a/cc/raster/raster_buffer_provider_unittest.cc b/cc/raster/raster_buffer_provider_unittest.cc
index 4618ad1e..16b1ed14 100644
--- a/cc/raster/raster_buffer_provider_unittest.cc
+++ b/cc/raster/raster_buffer_provider_unittest.cc
@@ -336,7 +336,7 @@
     auto gl_owned = std::make_unique<viz::TestGLES2Interface>();
     gl_owned->set_support_sync_query(true);
     context_provider_ = viz::TestContextProvider::Create(std::move(gl_owned));
-    context_provider_->BindToCurrentThread();
+    context_provider_->BindToCurrentSequence();
 
     worker_context_provider_ = viz::TestContextProvider::CreateWorker();
     DCHECK(worker_context_provider_);
diff --git a/cc/raster/scoped_gpu_raster_unittest.cc b/cc/raster/scoped_gpu_raster_unittest.cc
index b52983c3..069b8836 100644
--- a/cc/raster/scoped_gpu_raster_unittest.cc
+++ b/cc/raster/scoped_gpu_raster_unittest.cc
@@ -3,6 +3,9 @@
 // found in the LICENSE file.
 
 #include "cc/raster/scoped_gpu_raster.h"
+
+#include <memory>
+
 #include "components/viz/test/test_context_provider.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -18,7 +21,7 @@
 TEST(ScopedGpuRasterTest, RestoresUnpackAlignment) {
   scoped_refptr<viz::TestContextProvider> provider =
       viz::TestContextProvider::Create();
-  ASSERT_EQ(provider->BindToCurrentThread(), gpu::ContextResult::kSuccess);
+  ASSERT_EQ(provider->BindToCurrentSequence(), gpu::ContextResult::kSuccess);
   gpu::gles2::GLES2Interface* gl = provider->ContextGL();
   GLint unpack_alignment = 0;
   gl->GetIntegerv(GL_UNPACK_ALIGNMENT, &unpack_alignment);
diff --git a/cc/resources/resource_pool_unittest.cc b/cc/resources/resource_pool_unittest.cc
index 67435e35..6845046 100644
--- a/cc/resources/resource_pool_unittest.cc
+++ b/cc/resources/resource_pool_unittest.cc
@@ -32,7 +32,7 @@
     context_support_ = context_support.get();
     context_provider_ =
         viz::TestContextProvider::Create(std::move(context_support));
-    context_provider_->BindToCurrentThread();
+    context_provider_->BindToCurrentSequence();
     resource_provider_ = std::make_unique<viz::ClientResourceProvider>();
     test_task_runner_ = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
     resource_pool_ = std::make_unique<ResourcePool>(
diff --git a/cc/test/layer_tree_pixel_test.cc b/cc/test/layer_tree_pixel_test.cc
index 315baba..547f72a9 100644
--- a/cc/test/layer_tree_pixel_test.cc
+++ b/cc/test/layer_tree_pixel_test.cc
@@ -94,8 +94,9 @@
             worker_ri_type, /*support_locking=*/true);
     // Bind worker context to main thread like it is in production. This is
     // needed to fully initialize the context. Compositor context is bound to
-    // the impl thread in LayerTreeFrameSink::BindToCurrentThread().
-    gpu::ContextResult result = worker_context_provider->BindToCurrentThread();
+    // the impl thread in LayerTreeFrameSink::BindToCurrentSequence().
+    gpu::ContextResult result =
+        worker_context_provider->BindToCurrentSequence();
     DCHECK_EQ(result, gpu::ContextResult::kSuccess);
   }
   static constexpr bool disable_display_vsync = false;
diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc
index b989570e..7e70d49 100644
--- a/cc/test/pixel_test.cc
+++ b/cc/test/pixel_test.cc
@@ -279,7 +279,7 @@
   child_context_provider_ =
       base::MakeRefCounted<viz::TestInProcessContextProvider>(
           viz::TestContextType::kGLES2, /*support_locking=*/false);
-  gpu::ContextResult result = child_context_provider_->BindToCurrentThread();
+  gpu::ContextResult result = child_context_provider_->BindToCurrentSequence();
   DCHECK_EQ(result, gpu::ContextResult::kSuccess);
   child_resource_provider_ = std::make_unique<viz::ClientResourceProvider>();
 }
diff --git a/cc/tiles/gpu_image_decode_cache_perftest.cc b/cc/tiles/gpu_image_decode_cache_perftest.cc
index 545b7c5..6309466 100644
--- a/cc/tiles/gpu_image_decode_cache_perftest.cc
+++ b/cc/tiles/gpu_image_decode_cache_perftest.cc
@@ -51,7 +51,7 @@
                 /*support_locking=*/false)) {}
 
   void SetUp() override {
-    gpu::ContextResult result = context_provider_->BindToCurrentThread();
+    gpu::ContextResult result = context_provider_->BindToCurrentSequence();
     ASSERT_EQ(result, gpu::ContextResult::kSuccess);
     cache_ = std::make_unique<GpuImageDecodeCache>(
         context_provider_.get(), UseTransferCache(), kRGBA_8888_SkColorType,
diff --git a/cc/tiles/gpu_image_decode_cache_unittest.cc b/cc/tiles/gpu_image_decode_cache_unittest.cc
index 2f2b44e6..d613f1c 100644
--- a/cc/tiles/gpu_image_decode_cache_unittest.cc
+++ b/cc/tiles/gpu_image_decode_cache_unittest.cc
@@ -410,7 +410,7 @@
         advertise_accelerated_decoding_);
     discardable_manager_.SetGLES2Interface(
         context_provider_->UnboundTestContextGL());
-    context_provider_->BindToCurrentThread();
+    context_provider_->BindToCurrentSequence();
     {
       viz::RasterContextProvider::ScopedRasterContextLock context_lock(
           context_provider_.get());
diff --git a/cc/tiles/picture_layer_tiling_set_unittest.cc b/cc/tiles/picture_layer_tiling_set_unittest.cc
index f35bc39..4621461 100644
--- a/cc/tiles/picture_layer_tiling_set_unittest.cc
+++ b/cc/tiles/picture_layer_tiling_set_unittest.cc
@@ -244,7 +244,7 @@
                float expected_scale) {
     scoped_refptr<viz::TestContextProvider> context_provider =
         viz::TestContextProvider::Create();
-    ASSERT_EQ(context_provider->BindToCurrentThread(),
+    ASSERT_EQ(context_provider->BindToCurrentSequence(),
               gpu::ContextResult::kSuccess);
     std::unique_ptr<viz::ClientResourceProvider> resource_provider =
         std::make_unique<viz::ClientResourceProvider>();
diff --git a/cc/trees/layer_tree_frame_sink.cc b/cc/trees/layer_tree_frame_sink.cc
index 698fe1c..d3b7626 100644
--- a/cc/trees/layer_tree_frame_sink.cc
+++ b/cc/trees/layer_tree_frame_sink.cc
@@ -76,7 +76,7 @@
 
   if (context_provider_) {
     context_provider_->AddObserver(this);
-    auto result = context_provider_->BindToCurrentThread();
+    auto result = context_provider_->BindToCurrentSequence();
     if (result != gpu::ContextResult::kSuccess) {
       context_provider_->RemoveObserver(this);
       context_provider_ = nullptr;
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index e4db813..336762d 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -4048,7 +4048,7 @@
 void LayerTreeHostImpl::SetRenderFrameObserver(
     std::unique_ptr<RenderFrameMetadataObserver> observer) {
   render_frame_metadata_observer_ = std::move(observer);
-  render_frame_metadata_observer_->BindToCurrentThread();
+  render_frame_metadata_observer_->BindToCurrentSequence();
 }
 
 void LayerTreeHostImpl::WillScrollContent(ElementId element_id) {
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 96e4bb2..8d16e04 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -11271,7 +11271,7 @@
   gl_owned->set_have_post_sub_buffer(true);
   scoped_refptr<viz::TestContextProvider> context_provider(
       viz::TestContextProvider::Create(std::move(gl_owned)));
-  context_provider->BindToCurrentThread();
+  context_provider->BindToCurrentSequence();
 
   std::unique_ptr<FakeLayerTreeFrameSink> layer_tree_frame_sink(
       FakeLayerTreeFrameSink::Create3d(context_provider));
@@ -16791,7 +16791,7 @@
   TestRenderFrameMetadataObserver& operator=(
       const TestRenderFrameMetadataObserver&) = delete;
 
-  void BindToCurrentThread() override {}
+  void BindToCurrentSequence() override {}
   void OnRenderFrameSubmission(
       const RenderFrameMetadata& render_frame_metadata,
       viz::CompositorFrameMetadata* compositor_frame_metadata,
diff --git a/cc/trees/layer_tree_host_pixeltest_scrollbars.cc b/cc/trees/layer_tree_host_pixeltest_scrollbars.cc
index 7d63bd26..75615f1 100644
--- a/cc/trees/layer_tree_host_pixeltest_scrollbars.cc
+++ b/cc/trees/layer_tree_host_pixeltest_scrollbars.cc
@@ -155,7 +155,7 @@
 
   auto context = base::MakeRefCounted<viz::TestInProcessContextProvider>(
       viz::TestContextType::kGLES2, /*support_locking=*/false);
-  gpu::ContextResult result = context->BindToCurrentThread();
+  gpu::ContextResult result = context->BindToCurrentSequence();
   DCHECK_EQ(result, gpu::ContextResult::kSuccess);
   int max_texture_size = 0;
   context->ContextGL()->GetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index fee74e4..df29354 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -8937,7 +8937,7 @@
         : target_(target) {}
 
     // RenderFrameMetadataObserver implementation.
-    void BindToCurrentThread() override { target_->BindToCurrentThread(); }
+    void BindToCurrentSequence() override { target_->BindToCurrentSequence(); }
     void OnRenderFrameSubmission(
         const RenderFrameMetadata& render_frame_metadata,
         viz::CompositorFrameMetadata* compositor_frame_metadata,
@@ -8989,7 +8989,7 @@
   void AfterTest() override { EXPECT_EQ(1, num_force_sends_); }
 
   // RenderFrameMetadataObserver implementation. Called on thread.
-  void BindToCurrentThread() override {}
+  void BindToCurrentSequence() override {}
   void OnRenderFrameSubmission(
       const RenderFrameMetadata& render_frame_metadata,
       viz::CompositorFrameMetadata* compositor_frame_metadata,
@@ -9172,7 +9172,7 @@
         : target_(target) {}
 
     // RenderFrameMetadataObserver implementation.
-    void BindToCurrentThread() override { target_->BindToCurrentThread(); }
+    void BindToCurrentSequence() override { target_->BindToCurrentSequence(); }
     void OnRenderFrameSubmission(
         const RenderFrameMetadata& render_frame_metadata,
         viz::CompositorFrameMetadata* compositor_frame_metadata,
@@ -9246,7 +9246,7 @@
   }
 
   // RenderFrameMetadataObserver implementation.
-  void BindToCurrentThread() override {}
+  void BindToCurrentSequence() override {}
   void OnRenderFrameSubmission(
       const RenderFrameMetadata& render_frame_metadata,
       viz::CompositorFrameMetadata* compositor_frame_metadata,
diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc
index 68bfcd5..9267e9725 100644
--- a/cc/trees/layer_tree_host_unittest_context.cc
+++ b/cc/trees/layer_tree_host_unittest_context.cc
@@ -815,7 +815,7 @@
     context_should_support_io_surface_ = true;
 
     child_context_provider_ = viz::TestContextProvider::Create();
-    auto result = child_context_provider_->BindToCurrentThread();
+    auto result = child_context_provider_->BindToCurrentSequence();
     CHECK_EQ(result, gpu::ContextResult::kSuccess);
     shared_bitmap_manager_ = std::make_unique<viz::TestSharedBitmapManager>();
     child_resource_provider_ = std::make_unique<viz::ClientResourceProvider>();
diff --git a/cc/trees/layer_tree_host_unittest_copyrequest.cc b/cc/trees/layer_tree_host_unittest_copyrequest.cc
index 3135db0..91cc56a 100644
--- a/cc/trees/layer_tree_host_unittest_copyrequest.cc
+++ b/cc/trees/layer_tree_host_unittest_copyrequest.cc
@@ -877,7 +877,7 @@
   std::unique_ptr<viz::SkiaOutputSurface> CreateSkiaOutputSurfaceOnThread(
       viz::DisplayCompositorMemoryAndTaskController*) override {
     display_context_provider_ = viz::TestContextProvider::Create();
-    display_context_provider_->BindToCurrentThread();
+    display_context_provider_->BindToCurrentSequence();
     return viz::FakeSkiaOutputSurface::Create3d(display_context_provider_);
   }
 
@@ -1022,7 +1022,7 @@
   std::unique_ptr<viz::SkiaOutputSurface> CreateSkiaOutputSurfaceOnThread(
       viz::DisplayCompositorMemoryAndTaskController*) override {
     display_context_provider_ = viz::TestContextProvider::Create();
-    display_context_provider_->BindToCurrentThread();
+    display_context_provider_->BindToCurrentSequence();
     return viz::FakeSkiaOutputSurface::Create3d(display_context_provider_);
   }
 
diff --git a/cc/trees/render_frame_metadata_observer.h b/cc/trees/render_frame_metadata_observer.h
index fb225b5..a44d348 100644
--- a/cc/trees/render_frame_metadata_observer.h
+++ b/cc/trees/render_frame_metadata_observer.h
@@ -29,7 +29,7 @@
 
   // Binds on the current thread. This should only be called from the compositor
   // thread.
-  virtual void BindToCurrentThread() = 0;
+  virtual void BindToCurrentSequence() = 0;
 
   // Notification of the RendarFrameMetadata for the frame being submitted to
   // the display compositor.
diff --git a/chrome/MAJOR_BRANCH_DATE b/chrome/MAJOR_BRANCH_DATE
index 1c8fe71..813b998 100644
--- a/chrome/MAJOR_BRANCH_DATE
+++ b/chrome/MAJOR_BRANCH_DATE
@@ -1 +1 @@
-MAJOR_BRANCH_DATE=2022-09-16
+MAJOR_BRANCH_DATE=2022-10-14
diff --git a/chrome/VERSION b/chrome/VERSION
index aa3b185..efa7668 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
-MAJOR=108
+MAJOR=109
 MINOR=0
-BUILD=5359
+BUILD=5360
 PATCH=0
diff --git a/chrome/android/features/start_surface/OWNERS b/chrome/android/features/start_surface/OWNERS
index 714053a1..dd5703a 100644
--- a/chrome/android/features/start_surface/OWNERS
+++ b/chrome/android/features/start_surface/OWNERS
@@ -1,4 +1,3 @@
 hanxi@chromium.org
-spdonghao@chromium.org
 
 file://chrome/android/java/src/org/chromium/chrome/browser/tasks/OWNERS
diff --git a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartFeedTest.java b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartFeedTest.java
index 29389a7..55a9204 100644
--- a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartFeedTest.java
+++ b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartFeedTest.java
@@ -132,10 +132,6 @@
             Assert.assertFalse(
                     startSurfaceCoordinator.getMediatorForTesting().shouldShowFeedPlaceholder());
         });
-
-        // TODO(spdonghao): Add a test for Feed placeholder from warm start. It's tested in
-        // StartSurfaceMediatorUnitTest#feedPlaceholderFromWarmStart currently because warm start is
-        // hard to simulate here.
     }
 
     @Test
diff --git a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayoutTest.java b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayoutTest.java
index a2945cfd..af625805 100644
--- a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayoutTest.java
+++ b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayoutTest.java
@@ -296,7 +296,6 @@
     @MediumTest
     @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
     @CommandLineFlags.Add({BASE_PARAMS})
-    @DisabledTest(message = "https://crbug.com/1373499")
     public void testSwitchTabModel_ScrollToSelectedTab() throws IOException {
         ChromeTabbedActivity cta = mActivityTestRule.getActivity();
         prepareTabs(10, 0, "about:blank");
@@ -305,7 +304,6 @@
         CriteriaHelper.pollUiThread(() -> cta.getCurrentTabModel().isIncognito());
         enterTabSwitcher(cta);
         switchTabModel(cta, false);
-        TabUiTestHelper.verifyAllTabsHaveThumbnail(cta.getCurrentTabModel());
         // Make sure the grid tab switcher is scrolled down to show the selected tab.
         onView(tabSwitcherViewMatcher()).check((v, noMatchException) -> {
             if (noMatchException != null) throw noMatchException;
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java
index e73a52f..c5942464 100644
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java
+++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java
@@ -103,6 +103,9 @@
             if (!mSettingUpStreams) {
                 logSwitchedFeeds(newStream);
                 bindStream(newStream, /*shouldScrollToTop=*/true);
+                if (newStream.getStreamKind() == StreamKind.FOLLOWING) {
+                    FeedFeatures.updateFollowingFeedSeen();
+                }
             }
         }
 
@@ -557,6 +560,7 @@
                         if (feedContents.size() > mHeaderCount + 1) {
                             followingHeaderModel.set(
                                     SectionHeaderProperties.ANIMATION_START_KEY, true);
+                            FeedFeatures.updateNewIndicatorTimestamp();
                             mainFeedStream.removeOnContentChangedListener(this);
                         }
                     }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/tasks/OWNERS b/chrome/android/junit/src/org/chromium/chrome/browser/tasks/OWNERS
index 8240af0..be819bba 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/tasks/OWNERS
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/tasks/OWNERS
@@ -1,4 +1,3 @@
 file://chrome/android/java/src/org/chromium/chrome/browser/tasks/OWNERS
 
 per-file ReturnToChromeUtilUnitTest.java=hanxi@chromium.org
-per-file ReturnToChromeUtilUnitTest.java=spdonghao@chromium.org
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp
index fdfa6c9..f3b83ebe 100644
--- a/chrome/app/os_settings_strings.grdp
+++ b/chrome/app/os_settings_strings.grdp
@@ -4425,6 +4425,15 @@
   <message name="IDS_OS_SETTINGS_SMART_PRIVACY_QUICK_DIM_TITLE" desc="The name of the quick dim feature shown as the label of a toggle in the smart privacy subpage.">
     Lock-on-leave
   </message>
+  <message name="IDS_OS_SETTINGS_SMART_PRIVACY_QUICK_LOCK_LONG" desc="The name of the maximum value of the quick lock slider in the smart privacy subpage.">
+    Long
+  </message>
+    <message name="IDS_OS_SETTINGS_SMART_PRIVACY_QUICK_LOCK_SHORT" desc="The name of the minimum value of the quick lock slider in the smart privacy subpage.">
+    Short
+  </message>
+    <message name="IDS_OS_SETTINGS_SMART_PRIVACY_QUICK_LOCK_TITLE" desc="The text that shows the Time to lock for the quick lock slider in the smart privacy subpage.">
+    Time to lock
+  </message>
   <message name="IDS_OS_SETTINGS_SMART_PRIVACY_QUICK_DIM_SUBTEXT" desc="Sub-label elaborating on the meaning of smart screen locking.">
     If you move away from your device, your screen will lock automatically. When you're in front of your device, your screen will stay awake longer. If you aren't using a lock screen, your device will sleep instead of lock.
   </message>
diff --git a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_SMART_PRIVACY_QUICK_LOCK_LONG.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_SMART_PRIVACY_QUICK_LOCK_LONG.png.sha1
new file mode 100644
index 0000000..cdf46fd39
--- /dev/null
+++ b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_SMART_PRIVACY_QUICK_LOCK_LONG.png.sha1
@@ -0,0 +1 @@
+ebfca635b5c6429dc14ddb9208bc1763fefcd8f3
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_SMART_PRIVACY_QUICK_LOCK_SHORT.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_SMART_PRIVACY_QUICK_LOCK_SHORT.png.sha1
new file mode 100644
index 0000000..41eadb6b
--- /dev/null
+++ b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_SMART_PRIVACY_QUICK_LOCK_SHORT.png.sha1
@@ -0,0 +1 @@
+2e276eb85b252a452c664ed0a6200ec52078fe2d
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_SMART_PRIVACY_QUICK_LOCK_TITLE.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_SMART_PRIVACY_QUICK_LOCK_TITLE.png.sha1
new file mode 100644
index 0000000..40db7cd
--- /dev/null
+++ b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_SMART_PRIVACY_QUICK_LOCK_TITLE.png.sha1
@@ -0,0 +1 @@
+88bca81fa4cfa5d9948d1c9a785d6b4bba362d5b
\ No newline at end of file
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index b95cc2c..49f5319 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -3378,7 +3378,10 @@
     Clear displayed data?
   </message>
   <message name="IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_LEARN_MORE" desc="Label for first-party sets explainer with a learn more link shown when sites are filtered by first-party set owner">
-     These sites are in a group defined by <ph name="FPS_OWNER">$1<ex>google.com</ex></ph>. Sites in a group can see your activity in the group. <ph name="LINK_BEGIN">&lt;a&gt;</ph>Learn more<ph name="LINK_END">&lt;/a&gt;</ph>
+     These sites are in a group defined by <ph name="FPS_OWNER">$1<ex>google.com</ex></ph>. Sites in a group can see your activity in the group.
+  </message>
+  <message name="IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_LEARN_MORE_ACCESSIBILITY" desc="Accessibility label learn more link about first-party sets shown when user filters sites by first-party set owner">
+     Learn more about related sites in a new tab
   </message>
   <message name="IDS_SETTINGS_SITE_SETTINGS_CLEAR_ALL_STORAGE_DESCRIPTION" desc="Label describing how much total disk space chrome is using, next to the clear all button">
     Total storage used by sites: <ph name="TOTAL_USAGE">$1<ex>8 GB</ex></ph>
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_LEARN_MORE.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_LEARN_MORE.png.sha1
index 4e62f38..84b9cb4 100644
--- a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_LEARN_MORE.png.sha1
+++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_LEARN_MORE.png.sha1
@@ -1 +1 @@
-07c465bd8442b033868d2a8a648c7ee1fedb4d91
\ No newline at end of file
+de47c0d23ada6854c14cae9918721eb954c2545e
\ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_LEARN_MORE_ACCESSIBILITY.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_LEARN_MORE_ACCESSIBILITY.png.sha1
new file mode 100644
index 0000000..84b9cb4
--- /dev/null
+++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_LEARN_MORE_ACCESSIBILITY.png.sha1
@@ -0,0 +1 @@
+de47c0d23ada6854c14cae9918721eb954c2545e
\ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 68415e7..4761e2d 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -5418,6 +5418,8 @@
       "apps/app_service/app_service_proxy_lacros.h",
       "apps/app_service/browser_app_instance_forwarder.cc",
       "apps/app_service/browser_app_instance_forwarder.h",
+      "apps/app_service/metrics/website_metrics_service_lacros.cc",
+      "apps/app_service/metrics/website_metrics_service_lacros.h",
       "apps/digital_goods/digital_goods_factory_stub.cc",
       "apps/digital_goods/digital_goods_factory_stub.h",
       "apps/digital_goods/digital_goods_lacros.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 2e93f3f..58782a2 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -2263,6 +2263,8 @@
 
 const FeatureEntry::FeatureParam kWebFeedAwareness_new_animation[] = {
     {"awareness_style", "new_animation"}};
+const FeatureEntry::FeatureParam kWebFeedAwareness_new_animation_no_limit[] = {
+    {"awareness_style", "new_animation_no_limit"}};
 
 const FeatureEntry::FeatureParam kWebFeedAwareness_IPH[] = {
     {"awareness_style", "IPH"}};
@@ -2270,6 +2272,8 @@
 const FeatureEntry::FeatureVariation kWebFeedAwarenessVariations[] = {
     {"new animation", kWebFeedAwareness_new_animation,
      std::size(kWebFeedAwareness_new_animation), nullptr},
+    {"new animation rate limit off", kWebFeedAwareness_new_animation_no_limit,
+     std::size(kWebFeedAwareness_new_animation_no_limit), nullptr},
     {"IPH and dot", kWebFeedAwareness_IPH, std::size(kWebFeedAwareness_IPH),
      nullptr},
 };
@@ -4741,12 +4745,6 @@
      flag_descriptions::kOzonePlatformHintDescription, kOsLinux,
      MULTI_VALUE_TYPE(kOzonePlatformHintRuntimeChoices)},
 
-    {"clean-undecryptable-passwords",
-     flag_descriptions::kCleanUndecryptablePasswordsLinuxName,
-     flag_descriptions::kCleanUndecryptablePasswordsLinuxDescription, kOsLinux,
-     FEATURE_VALUE_TYPE(
-         password_manager::features::kSyncUndecryptablePasswordsLinux)},
-
     {"force-password-initial-sync-when-decryption-fails",
      flag_descriptions::kForcePasswordInitialSyncWhenDecryptionFailsName,
      flag_descriptions::kForcePasswordInitialSyncWhenDecryptionFailsDescription,
diff --git a/chrome/browser/apps/app_preload_service/app_preload_server_connector_unittest.cc b/chrome/browser/apps/app_preload_service/app_preload_server_connector_unittest.cc
index e6740de5..07a03c2 100644
--- a/chrome/browser/apps/app_preload_service/app_preload_server_connector_unittest.cc
+++ b/chrome/browser/apps/app_preload_service/app_preload_server_connector_unittest.cc
@@ -11,7 +11,6 @@
 #include "chrome/browser/apps/app_preload_service/device_info_manager.h"
 #include "chrome/browser/apps/app_preload_service/preload_app_definition.h"
 #include "chrome/browser/apps/app_preload_service/proto/app_provisioning.pb.h"
-#include "chrome/browser/apps/app_preload_service/proto/common.pb.h"
 #include "content/public/test/browser_task_environment.h"
 #include "net/http/http_request_headers.h"
 #include "services/network/public/cpp/resource_request.h"
@@ -86,8 +85,7 @@
 TEST_F(AppPreloadServerConnectorTest, GetAppsForFirstLoginSuccessfulResponse) {
   proto::AppProvisioningResponse response;
   auto* app = response.add_apps_to_install();
-  auto* app_group = app->mutable_app_group();
-  app_group->set_name("Peanut Types");
+  app->set_name("Peanut Types");
 
   url_loader_factory_.AddResponse(kServerUrl, response.SerializeAsString());
 
diff --git a/chrome/browser/apps/app_preload_service/app_preload_service_unittest.cc b/chrome/browser/apps/app_preload_service/app_preload_service_unittest.cc
index 13baad7a..0a69ed2 100644
--- a/chrome/browser/apps/app_preload_service/app_preload_service_unittest.cc
+++ b/chrome/browser/apps/app_preload_service/app_preload_service_unittest.cc
@@ -114,8 +114,7 @@
 TEST_F(AppPreloadServiceTest, FirstLoginPrefSet) {
   proto::AppProvisioningResponse response;
   auto* app = response.add_apps_to_install();
-  auto* app_group = app->mutable_app_group();
-  app_group->set_name("Peanut Types");
+  app->set_name("Peanut Types");
 
   url_loader_factory_.AddResponse(kServerUrl, response.SerializeAsString());
 
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 254c963..06dfe05a 100644
--- a/chrome/browser/apps/app_preload_service/preload_app_definition.cc
+++ b/chrome/browser/apps/app_preload_service/preload_app_definition.cc
@@ -7,7 +7,7 @@
 namespace apps {
 
 std::string PreloadAppDefinition::GetName() const {
-  return app_proto_.app_group().name();
+  return app_proto_.name();
 }
 
 std::ostream& operator<<(std::ostream& os, const PreloadAppDefinition& app) {
diff --git a/chrome/browser/apps/app_preload_service/proto/BUILD.gn b/chrome/browser/apps/app_preload_service/proto/BUILD.gn
index cffbcb6a..f316f08 100644
--- a/chrome/browser/apps/app_preload_service/proto/BUILD.gn
+++ b/chrome/browser/apps/app_preload_service/proto/BUILD.gn
@@ -5,8 +5,5 @@
 import("//third_party/protobuf/proto_library.gni")
 
 proto_library("proto") {
-  sources = [
-    "app_provisioning.proto",
-    "common.proto",
-  ]
+  sources = [ "app_provisioning.proto" ]
 }
diff --git a/chrome/browser/apps/app_preload_service/proto/app_provisioning.proto b/chrome/browser/apps/app_preload_service/proto/app_provisioning.proto
index 27ce897..f9d57eb 100644
--- a/chrome/browser/apps/app_preload_service/proto/app_provisioning.proto
+++ b/chrome/browser/apps/app_preload_service/proto/app_provisioning.proto
@@ -8,18 +8,121 @@
 
 package apps.proto;
 
-import "common.proto";
-
 // An identical copy of this proto is maintained in the server code base.
 // http://google3/chrome/chromeos/apps_foundation/almanac/fondue/boq/api/app_provisioning.proto
 // Any changes made here must also be made in the file above.
 // In the future this file will be add only, however breaking changes can be
 // be made until the interface is finalized (currently aimed for M110).
+
+// TODO(b/243338003): Review and finalise API. >> THIS IS A DRAFT API ONLY <<
+
+message AppProvisioningRequest {
+  // The board identifier for the device sending the request.
+  optional string board = 1;
+
+  // The model identifier for the device sending the request.
+  optional string model = 2;
+
+  // The SKU identifier for the device sending the request.
+  optional string sku_id = 3;
+
+  // The language-country identifier for the user in language in
+  // "language-COUNTRY" format, and must match one of the valid Google
+  // recognised codes. See:
+  // //i18n/identifiers/languagecodeconverter.h
+  // Note: this should ideally be the user's preferred language, if absent
+  // use the language specified by the UI. The server will attempt to honour
+  // this explicitly, but if it cannot it wil fall-back onto the next best
+  // available or en-US in the worst.case.
+  optional string language = 4;
+
+  // The ChromeOS version information.
+  optional ChromeOSVersion chrome_os_version = 5;
+
+  message ChromeOSVersion {
+    // Ash Chrome version.
+    optional string ash_chrome = 1;
+
+    // Chrome OS platform version.
+    optional string platform = 2;
+  }
+}
+
 message AppProvisioningResponse {
+  // A list of zero or more apps for APS to install.
   repeated App apps_to_install = 1;
+
+  enum Platform {
+    // Default for deserialization when an unexpected value is encountered.
+    // Indicates to the client that the server has a new platform not supported
+    // by this version of the proto.
+    PLATFORM_UNKNOWN = 0;
+
+    // A Web App.
+    PLATFORM_WEB = 1;
+
+    // An Android app managed by Play.
+    PLATFORM_ANDROID = 2;
+  }
+
+  message Icon {
+    // Url to query to get the icon. This will always be from the host
+    // meltingpot.googleusercontent.com.
+    optional string url = 1;
+
+    // Width of the icon in pixels. While App icons are typically square
+    // note there is no guarantee the image provided will be.
+    optional int32 width_in_pixels = 2;
+
+    // Mime type of the icon.
+    optional string mime_type = 3;
+
+    // Whether or not we have permission from the platform to mask the icon.
+    optional bool is_masking_allowed = 4;
+  }
+
+  // Every platform has its own [Platform]Extras message to store platform
+  // specific metadata.
+  // For Android-only metadata.
+  message AndroidExtras {
+    // |package_name| and |activity_name| uniquely identify each Android app.
+    optional string package_name = 1;
+    optional string activity_name = 2;
+  }
+
+  // For Web-only metadata.
+  message WebExtras {
+    // |start_url| and |manifest_id| uniquely identify each Web app.
+    optional string start_url = 1;
+    optional string manifest_id = 2;
+  }
+
   message App {
-    optional AppGroup app_group = 1;
-    optional int32 shelf_order = 2;
-    optional int32 launcher_order = 3;
+    // The identifier for the App Group that Fondue used to derive this app
+    // instance in the response.
+    // Note: this may not be unique in the apps_to_install collection.
+    optional string app_group_uuid = 1;
+
+    // The App's UTF-8 encoded name in the requested language (or next best).
+    optional string name = 2;
+
+    // One or more Icons for this App for the requested language (or next best).
+    repeated Icon icons = 3;
+
+    // Specifies the platform this app uses to install. This will match the
+    // contents of the extras.
+    optional Platform platform = 4;
+
+    // Platform-specific information for installing this app.
+    oneof extras {
+      AndroidExtras android_extras = 5;
+      WebExtras web_extras = 6;
+    }
+
+    // The shelf order for this app.
+    optional int32 shelf_order = 7;
+
+    // The launcher order for this app.
+    optional int32 launcher_order = 8;
   }
 }
diff --git a/chrome/browser/apps/app_preload_service/proto/common.proto b/chrome/browser/apps/app_preload_service/proto/common.proto
deleted file mode 100644
index cef4f6e..0000000
--- a/chrome/browser/apps/app_preload_service/proto/common.proto
+++ /dev/null
@@ -1,73 +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.
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package apps.proto;
-
-// An identical copy of this proto is maintained in the server code base.
-// http://google3/chrome/chromeos/apps_foundation/almanac/fondue/boq/api/common.proto
-// Any changes made here must also be made in the file above.
-// In the future this file will be add only, however breaking changes can be
-// be made until the interface is finalized (currently aimed for M110).
-
-// POTENTIAL APP_GROUP COMMON API
-// TODO(b/243338003): expand on this & potentially move to common API + document
-
-enum Platform {
-  PLATFORM_UNKNOWN = 0;
-  PLATFORM_WEB = 1;
-  PLATFORM_ANDROID = 2;
-}
-
-message Icon {
-  // Url to query to get the icon.
-  optional string url = 1;
-  // Size of the icon in pixels.
-  optional int32 size_in_pixels = 2;
-  // Mime type of the icon.
-  optional string mime_type = 3;
-  // Whether or not we have permission from the platform to mask the icon.
-  optional bool is_masking_allowed = 4;
-}
-
-// Every platform has its own [Platform]Extras message to store platform
-// specific metadata.
-// For Android-only metadata.
-message AndroidExtras {
-  // |package_name| and |activity_name| uniquely identify each Android app.
-  optional string package_name = 1;
-  optional string activity_name = 2;
-}
-
-// For Web-only metadata.
-message WebExtras {
-  // |start_url| and |manifest_id| uniquely identify each Android app.
-  optional string start_url = 1;
-  optional string manifest_id = 2;
-}
-
-// For fields shared across app platforms. Represents an instance of an app
-// regardless of what platform it's from.
-message AppInstance {
-  optional Platform platform = 1;
-
-  // For platform specific fields. The extras for an AppInstance should match
-  // the |platform| field above.
-  oneof extras {
-    AndroidExtras android_extras = 2;
-    WebExtras web_extras = 3;
-  }
-}
-
-// An Alamanac App Group which is a normalised unique app with multiple
-// installers.
-message AppGroup {
-  optional string uuid = 1;
-  optional string name = 2;
-  repeated Icon icons = 3;
-  repeated AppInstance app_instance = 4;
-}
diff --git a/chrome/browser/apps/app_service/app_service_proxy_lacros.cc b/chrome/browser/apps/app_service/app_service_proxy_lacros.cc
index a1413f37..b753485c 100644
--- a/chrome/browser/apps/app_service/app_service_proxy_lacros.cc
+++ b/chrome/browser/apps/app_service/app_service_proxy_lacros.cc
@@ -19,6 +19,7 @@
 #include "chrome/browser/apps/app_service/browser_app_instance_tracker.h"
 #include "chrome/browser/apps/app_service/intent_util.h"
 #include "chrome/browser/apps/app_service/launch_utils.h"
+#include "chrome/browser/apps/app_service/metrics/website_metrics_service_lacros.h"
 #include "chrome/browser/apps/app_service/publishers/extension_apps.h"
 #include "chrome/browser/extensions/extension_keeplist_chromeos.h"
 #include "chrome/browser/profiles/profile.h"
@@ -633,6 +634,13 @@
   content::URLDataSource::Add(profile_,
                               std::make_unique<apps::AppIconSource>(profile_));
 
+  if (!profile_->AsTestingProfile()) {
+    metrics_service_ = std::make_unique<WebsiteMetricsServiceLacros>();
+    base::ThreadTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE, base::BindOnce(&AppServiceProxyLacros::InitWebsiteMetrics,
+                                  weak_ptr_factory_.GetWeakPtr()));
+  }
+
   auto* service = chromeos::LacrosService::Get();
 
   if (!service || !service->IsAvailable<crosapi::mojom::AppServiceProxy>()) {
@@ -704,4 +712,10 @@
   remote_crosapi_app_service_proxy_->Launch(std::move(params));
 }
 
+void AppServiceProxyLacros::InitWebsiteMetrics() {
+  if (metrics_service_) {
+    metrics_service_->Start();
+  }
+}
+
 }  // namespace apps
diff --git a/chrome/browser/apps/app_service/app_service_proxy_lacros.h b/chrome/browser/apps/app_service/app_service_proxy_lacros.h
index 092aa28..9a9837b 100644
--- a/chrome/browser/apps/app_service/app_service_proxy_lacros.h
+++ b/chrome/browser/apps/app_service/app_service_proxy_lacros.h
@@ -53,6 +53,7 @@
 
 class BrowserAppInstanceForwarder;
 class BrowserAppInstanceTracker;
+class WebsiteMetricsServiceLacros;
 
 struct AppLaunchParams;
 
@@ -380,6 +381,8 @@
   // special handling.
   void ProxyLaunch(crosapi::mojom::LaunchParamsPtr params);
 
+  void InitWebsiteMetrics();
+
   apps::AppRegistryCache app_registry_cache_;
   apps::AppCapabilityAccessCache app_capability_access_cache_;
 
@@ -416,6 +419,8 @@
       nullptr;
   int crosapi_app_service_proxy_version_ = 0;
 
+  std::unique_ptr<apps::WebsiteMetricsServiceLacros> metrics_service_;
+
   base::WeakPtrFactory<AppServiceProxyLacros> weak_ptr_factory_{this};
 
  private:
diff --git a/chrome/browser/apps/app_service/metrics/app_platform_metrics_service.cc b/chrome/browser/apps/app_service/metrics/app_platform_metrics_service.cc
index f098f96..5eab07c 100644
--- a/chrome/browser/apps/app_service/metrics/app_platform_metrics_service.cc
+++ b/chrome/browser/apps/app_service/metrics/app_platform_metrics_service.cc
@@ -64,7 +64,8 @@
       profile_, app_registry_cache, instance_registry);
   app_platform_input_metrics_ = std::make_unique<apps::AppPlatformInputMetrics>(
       profile_, instance_registry);
-  website_metrics_ = std::make_unique<apps::WebsiteMetrics>(profile_);
+  website_metrics_ = std::make_unique<apps::WebsiteMetrics>(
+      profile_, GetUserTypeByDeviceTypeMetrics());
 
   day_id_ = profile_->GetPrefs()->GetInteger(kAppPlatformMetricsDayId);
   CheckForNewDay();
diff --git a/chrome/browser/apps/app_service/metrics/website_metrics.cc b/chrome/browser/apps/app_service/metrics/website_metrics.cc
index c6edf37..c55a0477 100644
--- a/chrome/browser/apps/app_service/metrics/website_metrics.cc
+++ b/chrome/browser/apps/app_service/metrics/website_metrics.cc
@@ -150,11 +150,12 @@
   return usage_time_dict;
 }
 
-WebsiteMetrics::WebsiteMetrics(Profile* profile)
-    : profile_(profile), browser_tab_strip_tracker_(this, nullptr) {
+WebsiteMetrics::WebsiteMetrics(Profile* profile, int user_type_by_device_type)
+    : profile_(profile),
+      browser_tab_strip_tracker_(this, nullptr),
+      user_type_by_device_type_(user_type_by_device_type) {
   BrowserList::GetInstance()->AddObserver(this);
   browser_tab_strip_tracker_.Init();
-  user_type_by_device_type_ = GetUserTypeByDeviceTypeMetrics();
   history::HistoryService* history_service =
       HistoryServiceFactory::GetForProfileWithoutCreating(profile);
   if (history_service) {
diff --git a/chrome/browser/apps/app_service/metrics/website_metrics.h b/chrome/browser/apps/app_service/metrics/website_metrics.h
index 1032c26..77cb3192 100644
--- a/chrome/browser/apps/app_service/metrics/website_metrics.h
+++ b/chrome/browser/apps/app_service/metrics/website_metrics.h
@@ -60,7 +60,7 @@
                        public wm::ActivationChangeObserver,
                        public history::HistoryServiceObserver {
  public:
-  explicit WebsiteMetrics(Profile* profile);
+  WebsiteMetrics(Profile* profile, int user_type_by_device_type);
 
   WebsiteMetrics(const WebsiteMetrics&) = delete;
   WebsiteMetrics& operator=(const WebsiteMetrics&) = delete;
diff --git a/chrome/browser/apps/app_service/metrics/website_metrics_browsertest.cc b/chrome/browser/apps/app_service/metrics/website_metrics_browsertest.cc
index 4522eeb..7ca5bef 100644
--- a/chrome/browser/apps/app_service/metrics/website_metrics_browsertest.cc
+++ b/chrome/browser/apps/app_service/metrics/website_metrics_browsertest.cc
@@ -33,7 +33,9 @@
 
 class TestWebsiteMetrics : public WebsiteMetrics {
  public:
-  explicit TestWebsiteMetrics(Profile* profile) : WebsiteMetrics(profile) {}
+  explicit TestWebsiteMetrics(Profile* profile)
+      : WebsiteMetrics(profile,
+                       /*user_type_by_device_type=*/0) {}
 
   void AwaitForInstallableWebAppCheck(const GURL& ukm_key) {
     if (on_checked_) {
diff --git a/chrome/browser/apps/app_service/metrics/website_metrics_service_lacros.cc b/chrome/browser/apps/app_service/metrics/website_metrics_service_lacros.cc
new file mode 100644
index 0000000..d01cad4
--- /dev/null
+++ b/chrome/browser/apps/app_service/metrics/website_metrics_service_lacros.cc
@@ -0,0 +1,48 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/apps/app_service/metrics/website_metrics_service_lacros.h"
+
+#include "base/time/time.h"
+
+namespace apps {
+
+namespace {
+
+// Interval for reporting noisy AppKM events.
+constexpr base::TimeDelta kNoisyAppKMReportInterval = base::Hours(2);
+
+// Check for app usage time, input event each 5 minutes.
+constexpr base::TimeDelta kFiveMinutes = base::Minutes(5);
+
+}  // namespace
+
+WebsiteMetricsServiceLacros::WebsiteMetricsServiceLacros() = default;
+
+WebsiteMetricsServiceLacros::~WebsiteMetricsServiceLacros() = default;
+
+void WebsiteMetricsServiceLacros::Start() {
+  // TODO(crbug.com/1334173): Create WebsiteMetrics to record website metrics.
+
+  // Check every `kFiveMinutes` to record websites usage time.
+  five_minutes_timer_.Start(FROM_HERE, kFiveMinutes, this,
+                            &WebsiteMetricsServiceLacros::CheckForFiveMinutes);
+
+  // Check every `kNoisyAppKMReportInterval` to report noisy AppKM events.
+  noisy_appkm_reporting_interval_timer_.Start(
+      FROM_HERE, kNoisyAppKMReportInterval, this,
+      &WebsiteMetricsServiceLacros::CheckForNoisyAppKMReportingInterval);
+}
+
+void WebsiteMetricsServiceLacros::CheckForFiveMinutes() {
+  // TODO(crbug.com/1334173): Call WebsiteMetrics OnFiveMinutes to record
+  // website metrics in the user pref.
+}
+
+void WebsiteMetricsServiceLacros::CheckForNoisyAppKMReportingInterval() {
+  // TODO(crbug.com/1334173): Call WebsiteMetrics OnTwoHours to log website
+  // metrics UKM.
+}
+
+}  // namespace apps
diff --git a/chrome/browser/apps/app_service/metrics/website_metrics_service_lacros.h b/chrome/browser/apps/app_service/metrics/website_metrics_service_lacros.h
new file mode 100644
index 0000000..e1ed8c0
--- /dev/null
+++ b/chrome/browser/apps/app_service/metrics/website_metrics_service_lacros.h
@@ -0,0 +1,45 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_APPS_APP_SERVICE_METRICS_WEBSITE_METRICS_SERVICE_LACROS_H_
+#define CHROME_BROWSER_APPS_APP_SERVICE_METRICS_WEBSITE_METRICS_SERVICE_LACROS_H_
+
+#include "base/timer/timer.h"
+
+namespace apps {
+
+// Service to initialize and control website metric recorders per day in the
+// Lacros side.
+class WebsiteMetricsServiceLacros {
+ public:
+  WebsiteMetricsServiceLacros();
+  WebsiteMetricsServiceLacros(const WebsiteMetricsServiceLacros&) = delete;
+  WebsiteMetricsServiceLacros& operator=(const WebsiteMetricsServiceLacros&) =
+      delete;
+  ~WebsiteMetricsServiceLacros();
+
+  // Start the timer for website metrics.
+  void Start();
+
+ private:
+  friend class WebsiteMetricsBrowserTest;
+
+  // Helper function to check if 5 mintues have arrived.
+  void CheckForFiveMinutes();
+
+  // Helper function to check if the reporting interval for noisy AppKMs has
+  // arrived to report noisy AppKMs events.
+  void CheckForNoisyAppKMReportingInterval();
+
+  // A periodic timer that checks if five minutes have arrived.
+  base::RepeatingTimer five_minutes_timer_;
+
+  // A periodic timer that checks if the reporting interval for noisy AppKMs has
+  // arrived to report noisy AppKM events.
+  base::RepeatingTimer noisy_appkm_reporting_interval_timer_;
+};
+
+}  // namespace apps
+
+#endif  // CHROME_BROWSER_APPS_APP_SERVICE_METRICS_WEBSITE_METRICS_SERVICE_LACROS_H_
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn
index 337832a..f7cce228 100644
--- a/chrome/browser/ash/BUILD.gn
+++ b/chrome/browser/ash/BUILD.gn
@@ -3051,8 +3051,6 @@
     "//ash/quick_pair/common",
     "//ash/services/device_sync/proto",
     "//ash/services/device_sync/public/cpp",
-    "//ash/services/ime/public/cpp:structs",
-    "//ash/services/ime/public/mojom",
     "//ash/services/multidevice_setup/public/cpp",
     "//ash/services/multidevice_setup/public/cpp:android_sms_app_helper_delegate",
     "//ash/services/multidevice_setup/public/cpp:android_sms_pairing_state_tracker",
@@ -3181,6 +3179,8 @@
     "//chromeos/ash/components/trash_service/public/cpp",
     "//chromeos/ash/services/cros_healthd/public/cpp",
     "//chromeos/ash/services/cros_healthd/public/mojom",
+    "//chromeos/ash/services/ime/public/cpp:structs",
+    "//chromeos/ash/services/ime/public/mojom",
     "//chromeos/ash/services/nearby/public/cpp",
     "//chromeos/ash/services/nearby/public/mojom",
     "//chromeos/ash/services/quick_pair/public/mojom:mojom_headers",
@@ -3385,7 +3385,6 @@
     "//ash/resources/vector_icons",
     "//ash/services/device_sync",
     "//ash/services/device_sync:stub_device_sync",
-    "//ash/services/ime:constants",
     "//ash/services/multidevice_setup",
     "//ash/services/multidevice_setup/public/cpp:oobe_completion_tracker",
     "//ash/services/multidevice_setup/public/cpp:prefs",
@@ -3522,6 +3521,7 @@
     "//chromeos/ash/services/assistant/public/cpp",
     "//chromeos/ash/services/bluetooth_config:in_process_bluetooth_config",
     "//chromeos/ash/services/cros_healthd/private/cpp",
+    "//chromeos/ash/services/ime:constants",
     "//chromeos/ash/services/quick_pair/public/mojom",
     "//chromeos/components/cdm_factory_daemon:cdm_factory_daemon_browser",
     "//chromeos/components/cdm_factory_daemon/mojom",
diff --git a/chrome/browser/ash/input_method/assistive_suggester.cc b/chrome/browser/ash/input_method/assistive_suggester.cc
index 53e82a1..afbb676 100644
--- a/chrome/browser/ash/input_method/assistive_suggester.cc
+++ b/chrome/browser/ash/input_method/assistive_suggester.cc
@@ -7,7 +7,6 @@
 #include "ash/constants/ash_features.h"
 #include "ash/constants/ash_pref_names.h"
 #include "ash/public/cpp/window_properties.h"
-#include "ash/services/ime/public/cpp/suggestions.h"
 #include "base/containers/fixed_flat_set.h"
 #include "base/feature_list.h"
 #include "base/hash/hash.h"
@@ -22,6 +21,7 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/common/pref_names.h"
+#include "chromeos/ash/services/ime/public/cpp/suggestions.h"
 #include "components/autofill/core/browser/personal_data_manager.h"
 #include "components/exo/wm_helper.h"
 #include "components/prefs/pref_service.h"
diff --git a/chrome/browser/ash/input_method/assistive_suggester.h b/chrome/browser/ash/input_method/assistive_suggester.h
index cdf54ade3..d886a77a 100644
--- a/chrome/browser/ash/input_method/assistive_suggester.h
+++ b/chrome/browser/ash/input_method/assistive_suggester.h
@@ -9,7 +9,6 @@
 #include <string>
 #include <vector>
 
-#include "ash/services/ime/public/cpp/suggestions.h"
 #include "base/memory/weak_ptr.h"
 #include "base/timer/timer.h"
 #include "chrome/browser/ash/input_method/assistive_suggester_switch.h"
@@ -21,6 +20,7 @@
 #include "chrome/browser/ash/input_method/suggestion_enums.h"
 #include "chrome/browser/ash/input_method/suggestion_handler_interface.h"
 #include "chrome/browser/ash/input_method/suggestions_source.h"
+#include "chromeos/ash/services/ime/public/cpp/suggestions.h"
 #include "components/autofill/core/browser/personal_data_manager.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
diff --git a/chrome/browser/ash/input_method/autocorrect_manager.cc b/chrome/browser/ash/input_method/autocorrect_manager.cc
index 061c128..81264d3 100644
--- a/chrome/browser/ash/input_method/autocorrect_manager.cc
+++ b/chrome/browser/ash/input_method/autocorrect_manager.cc
@@ -379,7 +379,8 @@
     return false;
   }
 
-  if (event.code() == ui::DomCode::ARROW_UP) {
+  if (event.code() == ui::DomCode::ARROW_UP ||
+      event.code() == ui::DomCode::TAB) {
     HighlightUndoButton();
     return true;
   }
diff --git a/chrome/browser/ash/input_method/autocorrect_manager_unittest.cc b/chrome/browser/ash/input_method/autocorrect_manager_unittest.cc
index 431e6be..8f84098 100644
--- a/chrome/browser/ash/input_method/autocorrect_manager_unittest.cc
+++ b/chrome/browser/ash/input_method/autocorrect_manager_unittest.cc
@@ -769,6 +769,31 @@
 }
 
 TEST_F(AutocorrectManagerTest,
+       PressingTabKeyHighlightsUndoButtonWhenUndoWindowIsVisible) {
+  manager_.OnSurroundingTextChanged(u"the ", /*cursor_pos=*/4,
+                                    /*anchor_pos=*/4);
+  manager_.HandleAutocorrect(gfx::Range(0, 3), u"teh", u"the");
+
+  {
+    ::testing::InSequence seq;
+
+    AssistiveWindowProperties shown_properties =
+        CreateVisibleUndoWindowProperties(u"teh", u"the");
+
+    EXPECT_CALL(mock_suggestion_handler_,
+                SetAssistiveWindowProperties(_, shown_properties, _));
+
+    ui::ime::AssistiveWindowButton button = CreateHighlightedUndoButton(u"teh");
+    EXPECT_CALL(mock_suggestion_handler_,
+                SetButtonHighlighted(_, button, true, _));
+  }
+
+  manager_.OnSurroundingTextChanged(u"the ", /*cursor_pos=*/1,
+                                    /*anchor_pos=*/1);
+  manager_.OnKeyEvent(CreateKeyEvent(ui::DomKey::NONE, ui::DomCode::TAB));
+}
+
+TEST_F(AutocorrectManagerTest,
        PressingEnterKeyHidesUndoWindowWhenButtonIsHighlighted) {
   manager_.OnSurroundingTextChanged(u"the ", /*cursor_pos=*/4,
                                     /*anchor_pos=*/4);
diff --git a/chrome/browser/ash/input_method/emoji_suggester.cc b/chrome/browser/ash/input_method/emoji_suggester.cc
index ed10a864..018241a 100644
--- a/chrome/browser/ash/input_method/emoji_suggester.cc
+++ b/chrome/browser/ash/input_method/emoji_suggester.cc
@@ -6,8 +6,6 @@
 
 #include "ash/constants/ash_features.h"
 #include "ash/constants/ash_pref_names.h"
-#include "ash/services/ime/constants.h"
-#include "ash/services/ime/public/cpp/suggestions.h"
 #include "base/files/file_util.h"
 #include "base/i18n/number_formatting.h"
 #include "base/metrics/field_trial_params.h"
@@ -23,6 +21,8 @@
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.h"
 #include "chrome/grit/generated_resources.h"
+#include "chromeos/ash/services/ime/constants.h"
+#include "chromeos/ash/services/ime/public/cpp/suggestions.h"
 #include "components/prefs/scoped_user_pref_update.h"
 #include "components/strings/grit/components_strings.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/chrome/browser/ash/input_method/emoji_suggester.h b/chrome/browser/ash/input_method/emoji_suggester.h
index ae8edd7..eae86480 100644
--- a/chrome/browser/ash/input_method/emoji_suggester.h
+++ b/chrome/browser/ash/input_method/emoji_suggester.h
@@ -7,13 +7,13 @@
 
 #include <string>
 
-#include "ash/services/ime/public/cpp/suggestions.h"
 #include "base/time/time.h"
 #include "chrome/browser/ash/input_method/input_method_engine.h"
 #include "chrome/browser/ash/input_method/suggester.h"
 #include "chrome/browser/ash/input_method/suggestion_enums.h"
 #include "chrome/browser/ash/input_method/suggestion_handler_interface.h"
 #include "chrome/browser/ash/input_method/ui/assistive_delegate.h"
+#include "chromeos/ash/services/ime/public/cpp/suggestions.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 class Profile;
diff --git a/chrome/browser/ash/input_method/ime_service_connector.cc b/chrome/browser/ash/input_method/ime_service_connector.cc
index 1427b4d..a1f5f0ff 100644
--- a/chrome/browser/ash/input_method/ime_service_connector.cc
+++ b/chrome/browser/ash/input_method/ime_service_connector.cc
@@ -7,9 +7,9 @@
 #include <memory>
 #include <utility>
 
-#include "ash/services/ime/constants.h"
-#include "ash/services/ime/public/mojom/ime_service.mojom.h"
 #include "base/files/file_util.h"
+#include "chromeos/ash/services/ime/constants.h"
+#include "chromeos/ash/services/ime/public/mojom/ime_service.mojom.h"
 #include "chromeos/strings/grit/chromeos_strings.h"
 #include "content/public/browser/service_process_host.h"
 #include "net/base/load_flags.h"
diff --git a/chrome/browser/ash/input_method/ime_service_connector.h b/chrome/browser/ash/input_method/ime_service_connector.h
index f93fdff..d3555ef 100644
--- a/chrome/browser/ash/input_method/ime_service_connector.h
+++ b/chrome/browser/ash/input_method/ime_service_connector.h
@@ -5,10 +5,10 @@
 #ifndef CHROME_BROWSER_ASH_INPUT_METHOD_IME_SERVICE_CONNECTOR_H_
 #define CHROME_BROWSER_ASH_INPUT_METHOD_IME_SERVICE_CONNECTOR_H_
 
-#include "ash/services/ime/public/mojom/ime_service.mojom.h"
 #include "base/base_paths.h"
 #include "base/files/file_path.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chromeos/ash/services/ime/public/mojom/ime_service.mojom.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
diff --git a/chrome/browser/ash/input_method/input_method_quick_settings_helpers.h b/chrome/browser/ash/input_method/input_method_quick_settings_helpers.h
index 2212618..a8b2ace 100644
--- a/chrome/browser/ash/input_method/input_method_quick_settings_helpers.h
+++ b/chrome/browser/ash/input_method/input_method_quick_settings_helpers.h
@@ -5,8 +5,8 @@
 #ifndef CHROME_BROWSER_ASH_INPUT_METHOD_INPUT_METHOD_QUICK_SETTINGS_HELPERS_H_
 #define CHROME_BROWSER_ASH_INPUT_METHOD_INPUT_METHOD_QUICK_SETTINGS_HELPERS_H_
 
-#include "ash/services/ime/public/mojom/input_method.mojom.h"
 #include "chrome/browser/ash/input_method/ui/input_method_menu_item.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method.mojom.h"
 
 namespace ash {
 namespace input_method {
diff --git a/chrome/browser/ash/input_method/input_method_settings.h b/chrome/browser/ash/input_method/input_method_settings.h
index faded7b..05eaad1 100644
--- a/chrome/browser/ash/input_method/input_method_settings.h
+++ b/chrome/browser/ash/input_method/input_method_settings.h
@@ -5,7 +5,7 @@
 #ifndef CHROME_BROWSER_ASH_INPUT_METHOD_INPUT_METHOD_SETTINGS_H_
 #define CHROME_BROWSER_ASH_INPUT_METHOD_INPUT_METHOD_SETTINGS_H_
 
-#include "ash/services/ime/public/mojom/input_method.mojom.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method.mojom.h"
 #include "components/prefs/pref_service.h"
 
 namespace ash {
diff --git a/chrome/browser/ash/input_method/longpress_diacritics_suggester.h b/chrome/browser/ash/input_method/longpress_diacritics_suggester.h
index 6f3f3bd5..0f6a1a7 100644
--- a/chrome/browser/ash/input_method/longpress_diacritics_suggester.h
+++ b/chrome/browser/ash/input_method/longpress_diacritics_suggester.h
@@ -7,7 +7,6 @@
 
 #include <string>
 
-#include "ash/services/ime/public/cpp/suggestions.h"
 #include "base/containers/fixed_flat_map.h"
 #include "base/strings/string_piece.h"
 #include "base/time/time.h"
@@ -15,6 +14,7 @@
 #include "chrome/browser/ash/input_method/suggestion_enums.h"
 #include "chrome/browser/ash/input_method/suggestion_handler_interface.h"
 #include "chrome/browser/ash/input_method/ui/assistive_delegate.h"
+#include "chromeos/ash/services/ime/public/cpp/suggestions.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/events/keycodes/dom/dom_code.h"
 
diff --git a/chrome/browser/ash/input_method/multi_word_suggester.cc b/chrome/browser/ash/input_method/multi_word_suggester.cc
index f2a1740..96f9c04 100644
--- a/chrome/browser/ash/input_method/multi_word_suggester.cc
+++ b/chrome/browser/ash/input_method/multi_word_suggester.cc
@@ -7,7 +7,6 @@
 #include <cmath>
 
 #include "ash/constants/ash_pref_names.h"
-#include "ash/services/ime/public/cpp/suggestions.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
@@ -16,6 +15,7 @@
 #include "base/time/time.h"
 #include "chrome/browser/ash/input_method/suggestion_enums.h"
 #include "chrome/browser/ash/input_method/ui/suggestion_details.h"
+#include "chromeos/ash/services/ime/public/cpp/suggestions.h"
 #include "components/prefs/scoped_user_pref_update.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/events/keycodes/dom/dom_code.h"
diff --git a/chrome/browser/ash/input_method/multi_word_suggester.h b/chrome/browser/ash/input_method/multi_word_suggester.h
index c6c8f108..394a816d 100644
--- a/chrome/browser/ash/input_method/multi_word_suggester.h
+++ b/chrome/browser/ash/input_method/multi_word_suggester.h
@@ -5,11 +5,11 @@
 #ifndef CHROME_BROWSER_ASH_INPUT_METHOD_MULTI_WORD_SUGGESTER_H_
 #define CHROME_BROWSER_ASH_INPUT_METHOD_MULTI_WORD_SUGGESTER_H_
 
-#include "ash/services/ime/public/cpp/suggestions.h"
 #include "base/time/time.h"
 #include "chrome/browser/ash/input_method/suggester.h"
 #include "chrome/browser/ash/input_method/suggestion_enums.h"
 #include "chrome/browser/ash/input_method/suggestion_handler_interface.h"
+#include "chromeos/ash/services/ime/public/cpp/suggestions.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace ash {
diff --git a/chrome/browser/ash/input_method/multi_word_suggester_unittest.cc b/chrome/browser/ash/input_method/multi_word_suggester_unittest.cc
index 2e892dc..2d56f30 100644
--- a/chrome/browser/ash/input_method/multi_word_suggester_unittest.cc
+++ b/chrome/browser/ash/input_method/multi_word_suggester_unittest.cc
@@ -8,11 +8,11 @@
 #include <vector>
 
 #include "ash/constants/ash_pref_names.h"
-#include "ash/services/ime/public/cpp/suggestions.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/time/time.h"
 #include "chrome/browser/ash/input_method/fake_suggestion_handler.h"
 #include "chrome/test/base/testing_profile.h"
+#include "chromeos/ash/services/ime/public/cpp/suggestions.h"
 #include "components/prefs/scoped_user_pref_update.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/ash/input_method/native_input_method_engine.cc b/chrome/browser/ash/input_method/native_input_method_engine.cc
index 66ca41b..b607354 100644
--- a/chrome/browser/ash/input_method/native_input_method_engine.cc
+++ b/chrome/browser/ash/input_method/native_input_method_engine.cc
@@ -8,7 +8,6 @@
 
 #include "ash/constants/ash_features.h"
 #include "ash/constants/ash_pref_names.h"
-#include "ash/services/ime/public/mojom/input_method.mojom.h"
 #include "base/feature_list.h"
 #include "base/i18n/i18n_constants.h"
 #include "base/i18n/icu_string_conversions.h"
@@ -36,6 +35,7 @@
 #include "chrome/browser/ui/settings_window_manager_chromeos.h"
 #include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h"
 #include "chrome/common/pref_names.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method.mojom.h"
 #include "components/prefs/pref_service.h"
 #include "ui/base/ime/ash/extension_ime_util.h"
 #include "ui/base/ime/ash/ime_bridge.h"
diff --git a/chrome/browser/ash/input_method/native_input_method_engine.h b/chrome/browser/ash/input_method/native_input_method_engine.h
index 4e2065c..ca22a616 100644
--- a/chrome/browser/ash/input_method/native_input_method_engine.h
+++ b/chrome/browser/ash/input_method/native_input_method_engine.h
@@ -5,11 +5,6 @@
 #ifndef CHROME_BROWSER_ASH_INPUT_METHOD_NATIVE_INPUT_METHOD_ENGINE_H_
 #define CHROME_BROWSER_ASH_INPUT_METHOD_NATIVE_INPUT_METHOD_ENGINE_H_
 
-#include "ash/services/ime/public/cpp/suggestions.h"
-#include "ash/services/ime/public/mojom/connection_factory.mojom.h"
-#include "ash/services/ime/public/mojom/input_engine.mojom.h"
-#include "ash/services/ime/public/mojom/input_method.mojom.h"
-#include "ash/services/ime/public/mojom/input_method_host.mojom.h"
 #include "base/memory/weak_ptr.h"
 #include "base/scoped_observation.h"
 #include "chrome/browser/ash/input_method/assistive_suggester.h"
@@ -20,6 +15,11 @@
 #include "chrome/browser/ash/input_method/native_input_method_engine_observer.h"
 #include "chrome/browser/ash/input_method/suggestions_collector.h"
 #include "chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.h"
+#include "chromeos/ash/services/ime/public/cpp/suggestions.h"
+#include "chromeos/ash/services/ime/public/mojom/connection_factory.mojom.h"
+#include "chromeos/ash/services/ime/public/mojom/input_engine.mojom.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method.mojom.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method_host.mojom.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "components/prefs/pref_service.h"
 #include "mojo/public/cpp/bindings/associated_receiver.h"
diff --git a/chrome/browser/ash/input_method/native_input_method_engine_observer.cc b/chrome/browser/ash/input_method/native_input_method_engine_observer.cc
index 24cf00bc..1c410b2f 100644
--- a/chrome/browser/ash/input_method/native_input_method_engine_observer.cc
+++ b/chrome/browser/ash/input_method/native_input_method_engine_observer.cc
@@ -8,7 +8,6 @@
 
 #include "ash/constants/ash_features.h"
 #include "ash/constants/ash_pref_names.h"
-#include "ash/services/ime/public/mojom/input_method.mojom.h"
 #include "base/feature_list.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
@@ -22,11 +21,13 @@
 #include "chrome/browser/ash/input_method/diacritics_checker.h"
 #include "chrome/browser/ash/input_method/input_method_quick_settings_helpers.h"
 #include "chrome/browser/ash/input_method/input_method_settings.h"
+#include "chrome/browser/ash/input_method/suggestion_enums.h"
 #include "chrome/browser/ash/input_method/ui/input_method_menu_manager.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/settings_window_manager_chromeos.h"
 #include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h"
 #include "chrome/common/pref_names.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method.mojom.h"
 #include "components/prefs/pref_service.h"
 #include "ui/base/ime/ash/extension_ime_util.h"
 #include "ui/base/ime/ash/ime_bridge.h"
@@ -421,6 +422,18 @@
                              : ui::ImeTextSpan::UnderlineStyle::kSolid);
 }
 
+MultiWordSuggestionType ToUmaSuggestionType(
+    const ime::TextSuggestionMode& mode) {
+  switch (mode) {
+    case ime::TextSuggestionMode::kCompletion:
+      return MultiWordSuggestionType::kCompletion;
+    case ime::TextSuggestionMode::kPrediction:
+      return MultiWordSuggestionType::kPrediction;
+    default:
+      return MultiWordSuggestionType::kUnknown;
+  }
+}
+
 void OnConnected(bool bound) {
   LogEvent(bound ? ImeServiceEvent::kActivateImeSuccess
                  : ImeServiceEvent::kActivateImeFailed);
@@ -1186,6 +1199,13 @@
                             settings->layout);
 }
 
+void NativeInputMethodEngineObserver::ReportSuggestionOpportunity(
+    ime::TextSuggestionMode mode) {
+  base::UmaHistogramEnumeration(
+      "InputMethod.Assistive.MultiWord.SuggestionOpportunity",
+      ToUmaSuggestionType(mode));
+}
+
 void NativeInputMethodEngineObserver::UpdateQuickSettings(
     mojom::InputMethodQuickSettingsPtr quick_settings) {
   ui::ime::InputMethodMenuManager::GetInstance()
diff --git a/chrome/browser/ash/input_method/native_input_method_engine_observer.h b/chrome/browser/ash/input_method/native_input_method_engine_observer.h
index 4119c3e2..70c53c9 100644
--- a/chrome/browser/ash/input_method/native_input_method_engine_observer.h
+++ b/chrome/browser/ash/input_method/native_input_method_engine_observer.h
@@ -4,11 +4,6 @@
 #ifndef CHROME_BROWSER_ASH_INPUT_METHOD_NATIVE_INPUT_METHOD_ENGINE_OBSERVER_H_
 #define CHROME_BROWSER_ASH_INPUT_METHOD_NATIVE_INPUT_METHOD_ENGINE_OBSERVER_H_
 
-#include "ash/services/ime/public/cpp/suggestions.h"
-#include "ash/services/ime/public/mojom/connection_factory.mojom.h"
-#include "ash/services/ime/public/mojom/input_engine.mojom.h"
-#include "ash/services/ime/public/mojom/input_method.mojom.h"
-#include "ash/services/ime/public/mojom/input_method_host.mojom.h"
 #include "base/memory/weak_ptr.h"
 #include "base/scoped_observation.h"
 #include "chrome/browser/ash/input_method/assistive_suggester.h"
@@ -18,6 +13,11 @@
 #include "chrome/browser/ash/input_method/input_method_engine.h"
 #include "chrome/browser/ash/input_method/suggestions_collector.h"
 #include "chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.h"
+#include "chromeos/ash/services/ime/public/cpp/suggestions.h"
+#include "chromeos/ash/services/ime/public/mojom/connection_factory.mojom.h"
+#include "chromeos/ash/services/ime/public/mojom/input_engine.mojom.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method.mojom.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method_host.mojom.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "components/prefs/pref_service.h"
 #include "mojo/public/cpp/bindings/associated_receiver.h"
@@ -111,6 +111,7 @@
   void RecordUkm(ime::mojom::UkmEntryPtr entry) override;
   void ReportKoreanAction(ime::mojom::KoreanAction action) override;
   void ReportKoreanSettings(ime::mojom::KoreanSettingsPtr settings) override;
+  void ReportSuggestionOpportunity(ime::TextSuggestionMode mode) override;
   void UpdateQuickSettings(
       ime::mojom::InputMethodQuickSettingsPtr quick_settings) override;
 
diff --git a/chrome/browser/ash/input_method/native_input_method_engine_observer_unittest.cc b/chrome/browser/ash/input_method/native_input_method_engine_observer_unittest.cc
new file mode 100644
index 0000000..30f8058
--- /dev/null
+++ b/chrome/browser/ash/input_method/native_input_method_engine_observer_unittest.cc
@@ -0,0 +1,62 @@
+// 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.
+
+#include "chrome/browser/ash/input_method/native_input_method_engine_observer.h"
+
+#include "base/test/metrics/histogram_tester.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace ash::input_method {
+namespace {
+
+class NativeInputMethodEngineObserverTest : public ::testing::Test {
+ public:
+  NativeInputMethodEngineObserverTest()
+      : observer_(/*prefs=*/nullptr,
+                  /*ime_base_observer=*/nullptr,
+                  /*assistive_suggester=*/nullptr,
+                  /*autocorrect_manager=*/nullptr,
+                  /*suggestions_collector=*/nullptr,
+                  /*grammar_manager=*/nullptr,
+                  /*use_ime_service=*/false) {}
+
+ protected:
+  NativeInputMethodEngineObserver observer_;
+};
+
+TEST_F(NativeInputMethodEngineObserverTest,
+       RecordsSuggestionOpportunityForCompletions) {
+  base::HistogramTester histogram_tester;
+  histogram_tester.ExpectTotalCount(
+      "InputMethod.Assistive.MultiWord.SuggestionOpportunity", 0);
+
+  observer_.ReportSuggestionOpportunity(ime::TextSuggestionMode::kCompletion);
+
+  histogram_tester.ExpectTotalCount(
+      "InputMethod.Assistive.MultiWord.SuggestionOpportunity", 1);
+  histogram_tester.ExpectUniqueSample(
+      "InputMethod.Assistive.MultiWord.SuggestionOpportunity",
+      /*sample=*/MultiWordSuggestionType::kCompletion,
+      /*expected_bucket_count=*/1);
+}
+
+TEST_F(NativeInputMethodEngineObserverTest,
+       RecordsSuggestionOpportunityForPredictions) {
+  base::HistogramTester histogram_tester;
+  histogram_tester.ExpectTotalCount(
+      "InputMethod.Assistive.MultiWord.SuggestionOpportunity", 0);
+
+  observer_.ReportSuggestionOpportunity(ime::TextSuggestionMode::kPrediction);
+
+  histogram_tester.ExpectTotalCount(
+      "InputMethod.Assistive.MultiWord.SuggestionOpportunity", 1);
+  histogram_tester.ExpectUniqueSample(
+      "InputMethod.Assistive.MultiWord.SuggestionOpportunity",
+      /*sample=*/MultiWordSuggestionType::kPrediction,
+      /*expected_bucket_count=*/1);
+}
+
+}  // namespace
+}  // namespace ash::input_method
diff --git a/chrome/browser/ash/input_method/native_input_method_engine_unittest.cc b/chrome/browser/ash/input_method/native_input_method_engine_unittest.cc
index 20debcd..99080c4 100644
--- a/chrome/browser/ash/input_method/native_input_method_engine_unittest.cc
+++ b/chrome/browser/ash/input_method/native_input_method_engine_unittest.cc
@@ -6,14 +6,14 @@
 
 #include "ash/constants/ash_features.h"
 #include "ash/constants/ash_pref_names.h"
-#include "ash/services/ime/public/mojom/input_engine.mojom.h"
-#include "ash/services/ime/public/mojom/input_method.mojom.h"
 #include "base/callback_helpers.h"
 #include "base/feature_list.h"
 #include "chrome/browser/ash/input_method/stub_input_method_engine_observer.h"
 #include "chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client_test_helper.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
+#include "chromeos/ash/services/ime/public/mojom/input_engine.mojom.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method.mojom.h"
 #include "chromeos/services/machine_learning/public/cpp/fake_service_connection.h"
 #include "components/ukm/content/source_url_recorder.h"
 #include "components/ukm/test_ukm_recorder.h"
diff --git a/chrome/browser/ash/input_method/personal_info_suggester.cc b/chrome/browser/ash/input_method/personal_info_suggester.cc
index 4f973a4..bcef0136 100644
--- a/chrome/browser/ash/input_method/personal_info_suggester.cc
+++ b/chrome/browser/ash/input_method/personal_info_suggester.cc
@@ -6,7 +6,6 @@
 
 #include "ash/constants/ash_features.h"
 #include "ash/constants/ash_pref_names.h"
-#include "ash/services/ime/public/cpp/suggestions.h"
 #include "base/feature_list.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/no_destructor.h"
@@ -20,6 +19,7 @@
 #include "chrome/browser/extensions/api/input_ime/input_ime_api.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.h"
+#include "chromeos/ash/services/ime/public/cpp/suggestions.h"
 #include "components/autofill/core/browser/data_model/autofill_profile.h"
 #include "components/autofill/core/browser/personal_data_manager.h"
 #include "components/autofill/core/browser/ui/label_formatter_utils.h"
diff --git a/chrome/browser/ash/input_method/personal_info_suggester.h b/chrome/browser/ash/input_method/personal_info_suggester.h
index 6eff096dc..81462db 100644
--- a/chrome/browser/ash/input_method/personal_info_suggester.h
+++ b/chrome/browser/ash/input_method/personal_info_suggester.h
@@ -7,13 +7,13 @@
 
 #include <string>
 
-#include "ash/services/ime/public/cpp/suggestions.h"
 #include "base/time/time.h"
 #include "chrome/browser/ash/input_method/input_method_engine.h"
 #include "chrome/browser/ash/input_method/suggester.h"
 #include "chrome/browser/ash/input_method/suggestion_enums.h"
 #include "chrome/browser/ash/input_method/suggestion_handler_interface.h"
 #include "chrome/browser/extensions/api/input_ime/input_ime_api.h"
+#include "chromeos/ash/services/ime/public/cpp/suggestions.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace autofill {
diff --git a/chrome/browser/ash/input_method/suggestions_collector.cc b/chrome/browser/ash/input_method/suggestions_collector.cc
index ad53514b..fdf24e5 100644
--- a/chrome/browser/ash/input_method/suggestions_collector.cc
+++ b/chrome/browser/ash/input_method/suggestions_collector.cc
@@ -4,9 +4,9 @@
 
 #include "chrome/browser/ash/input_method/suggestions_collector.h"
 
-#include "ash/services/ime/public/cpp/suggestions.h"
-#include "ash/services/ime/public/mojom/input_engine.mojom.h"
 #include "base/callback.h"
+#include "chromeos/ash/services/ime/public/cpp/suggestions.h"
+#include "chromeos/ash/services/ime/public/mojom/input_engine.mojom.h"
 
 namespace ash {
 namespace input_method {
diff --git a/chrome/browser/ash/input_method/suggestions_collector.h b/chrome/browser/ash/input_method/suggestions_collector.h
index d7058ac..f4b26804 100644
--- a/chrome/browser/ash/input_method/suggestions_collector.h
+++ b/chrome/browser/ash/input_method/suggestions_collector.h
@@ -8,10 +8,10 @@
 #include <memory>
 #include <vector>
 
-#include "ash/services/ime/public/cpp/suggestions.h"
-#include "ash/services/ime/public/mojom/input_method_host.mojom.h"
 #include "base/callback.h"
 #include "chrome/browser/ash/input_method/suggestions_source.h"
+#include "chromeos/ash/services/ime/public/cpp/suggestions.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method_host.mojom.h"
 
 namespace ash {
 namespace input_method {
diff --git a/chrome/browser/ash/input_method/suggestions_collector_unittest.cc b/chrome/browser/ash/input_method/suggestions_collector_unittest.cc
index 13cfb6a..75ba8a0 100644
--- a/chrome/browser/ash/input_method/suggestions_collector_unittest.cc
+++ b/chrome/browser/ash/input_method/suggestions_collector_unittest.cc
@@ -6,11 +6,11 @@
 
 #include <vector>
 
-#include "ash/services/ime/public/cpp/suggestions.h"
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/test/bind.h"
 #include "chrome/browser/ash/input_method/suggestions_source.h"
+#include "chromeos/ash/services/ime/public/cpp/suggestions.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace ash {
diff --git a/chrome/browser/ash/input_method/suggestions_service_client.h b/chrome/browser/ash/input_method/suggestions_service_client.h
index ea74f5e..2048538 100644
--- a/chrome/browser/ash/input_method/suggestions_service_client.h
+++ b/chrome/browser/ash/input_method/suggestions_service_client.h
@@ -7,11 +7,11 @@
 
 #include <vector>
 
-#include "ash/services/ime/public/cpp/suggestions.h"
 #include "base/callback.h"
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
 #include "chrome/browser/ash/input_method/suggestions_source.h"
+#include "chromeos/ash/services/ime/public/cpp/suggestions.h"
 #include "chromeos/services/machine_learning/public/mojom/machine_learning_service.mojom.h"
 #include "chromeos/services/machine_learning/public/mojom/text_suggester.mojom.h"
 #include "mojo/public/cpp/bindings/remote.h"
diff --git a/chrome/browser/ash/input_method/suggestions_source.h b/chrome/browser/ash/input_method/suggestions_source.h
index cbd4dee..dd259b75 100644
--- a/chrome/browser/ash/input_method/suggestions_source.h
+++ b/chrome/browser/ash/input_method/suggestions_source.h
@@ -7,8 +7,8 @@
 
 #include <vector>
 
-#include "ash/services/ime/public/cpp/suggestions.h"
 #include "base/callback.h"
+#include "chromeos/ash/services/ime/public/cpp/suggestions.h"
 
 namespace ash {
 namespace input_method {
diff --git a/chrome/browser/ash/login/easy_unlock/easy_unlock_service_regular.cc b/chrome/browser/ash/login/easy_unlock/easy_unlock_service_regular.cc
index 341d6b0..e8f33e8d 100644
--- a/chrome/browser/ash/login/easy_unlock/easy_unlock_service_regular.cc
+++ b/chrome/browser/ash/login/easy_unlock/easy_unlock_service_regular.cc
@@ -33,7 +33,7 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/gcm/gcm_profile_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.h"
+#include "chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_dialog.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/ash/components/multidevice/logging/logging.h"
diff --git a/chrome/browser/ash/login/easy_unlock/easy_unlock_service_regular_unittest.cc b/chrome/browser/ash/login/easy_unlock/easy_unlock_service_regular_unittest.cc
index ab3f32a..a04b6bf7 100644
--- a/chrome/browser/ash/login/easy_unlock/easy_unlock_service_regular_unittest.cc
+++ b/chrome/browser/ash/login/easy_unlock/easy_unlock_service_regular_unittest.cc
@@ -32,7 +32,7 @@
 #include "chrome/browser/ash/login/users/mock_user_manager.h"
 #include "chrome/browser/prefs/browser_prefs.h"
 #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
-#include "chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.h"
+#include "chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_dialog.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
diff --git a/chrome/browser/ash/login/screens/user_selection_screen.cc b/chrome/browser/ash/login/screens/user_selection_screen.cc
index 93ee096be..d7a148e 100644
--- a/chrome/browser/ash/login/screens/user_selection_screen.cc
+++ b/chrome/browser/ash/login/screens/user_selection_screen.cc
@@ -522,11 +522,6 @@
     avatar.bytes.assign(avatar_data.begin(), avatar_data.end());
   };
 
-  // After the default avatar images are moved to cloud, the user
-  // should have image bytes when using default images.
-  CHECK(!ash::features::IsAvatarsCloudMigrationEnabled() ||
-        !user.HasDefaultImage() || user.has_image_bytes());
-
   // After the avatar cloud migration, remove the second if case.
   if (user.has_image_bytes()) {
     avatar.bytes.assign(
diff --git a/chrome/browser/ash/login/users/avatar/user_image_loader.cc b/chrome/browser/ash/login/users/avatar/user_image_loader.cc
index c8bec3e7..5208936 100644
--- a/chrome/browser/ash/login/users/avatar/user_image_loader.cc
+++ b/chrome/browser/ash/login/users/avatar/user_image_loader.cc
@@ -13,6 +13,7 @@
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/task/task_runner_util.h"
@@ -42,6 +43,8 @@
 namespace user_image_loader {
 namespace {
 
+constexpr const char kURLLoaderDownloadSuccessHistogramName[] =
+    "Ash.UserImage.URLLoaderDownloadSuccess";
 constexpr int64_t kMaxImageSizeInBytes =
     static_cast<int64_t>(IPC::Channel::kMaximumMessageSize);
 
@@ -350,11 +353,13 @@
                        LoadedCallback loaded_cb,
                        std::unique_ptr<std::string> body) {
   if (loader->NetError() != net::OK || !body) {
+    base::UmaHistogramBoolean(kURLLoaderDownloadSuccessHistogramName, false);
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE, base::BindOnce(std::move(loaded_cb),
                                   std::make_unique<user_manager::UserImage>()));
     return;
   }
+  base::UmaHistogramBoolean(kURLLoaderDownloadSuccessHistogramName, true);
   DecodeAnimation(std::move(loaded_cb), *body);
 }
 
diff --git a/chrome/browser/ash/login/users/avatar/user_image_manager_impl.cc b/chrome/browser/ash/login/users/avatar/user_image_manager_impl.cc
index d45bb8d..7182a46 100644
--- a/chrome/browser/ash/login/users/avatar/user_image_manager_impl.cc
+++ b/chrome/browser/ash/login/users/avatar/user_image_manager_impl.cc
@@ -235,17 +235,6 @@
   // Notifies the `parent_` that the Job is done.
   void NotifyJobDone();
 
-  const base::Value::Dict* GetImageProperties() {
-    PrefService* local_state = g_browser_process->local_state();
-    const base::Value::Dict& prefs_images =
-        local_state->GetDict(kUserImageProperties);
-
-    const base::Value::Dict* image_properties =
-        prefs_images.FindDict(account_id().GetUserEmail());
-
-    return image_properties;
-  }
-
   const AccountId& account_id() const { return parent_->account_id_; }
 
   UserImageManagerImpl* parent_;
@@ -279,7 +268,8 @@
     // Load one of the default images. This happens synchronously.
     if (ash::features::IsAvatarsCloudMigrationEnabled()) {
       bool image_cache_updated = false;
-      if (const base::Value::Dict* image_properties = GetImageProperties()) {
+      if (const base::Value::Dict* image_properties =
+              parent_->GetImageProperties()) {
         image_cache_updated =
             image_properties->FindBool(kImageCacheUpdated).value_or(false);
       }
@@ -311,7 +301,6 @@
       // images to cloud.
       UpdateUserAndSaveImage(std::move(user_image));
     }
-
   } else if (image_index_ == user_manager::User::USER_IMAGE_EXTERNAL ||
              image_index_ == user_manager::User::USER_IMAGE_PROFILE) {
     // Load the user image from a file referenced by `image_path`. This happens
@@ -494,7 +483,8 @@
   base::FilePath old_image_path;
   // Because the user ID (i.e. email address) contains '.', the code here
   // cannot use the dots notation (path expantion) hence is verbose.
-  if (const base::Value::Dict* image_properties = GetImageProperties()) {
+  if (const base::Value::Dict* image_properties =
+          parent_->GetImageProperties()) {
     const std::string* value = image_properties->FindString(kImagePathNodeName);
     if (value)
       old_image_path = base::FilePath::FromUTF8Unsafe(*value);
@@ -524,7 +514,9 @@
   base::Value::Dict entry;
   entry.Set(kImagePathNodeName, image_path_.value());
   entry.Set(kImageIndexNodeName, image_index_);
-  entry.Set(kImageCacheUpdated, true);
+  // TODO: set to true after we can cache animated avatars.
+  // See b/250810109 for more context.
+  entry.Set(kImageCacheUpdated, false);
   if (!image_url_.is_empty())
     entry.Set(kImageURLNodeName, image_url_.spec());
 
@@ -563,20 +555,13 @@
 UserImageManagerImpl::~UserImageManagerImpl() {}
 
 void UserImageManagerImpl::LoadUserImage() {
-  PrefService* local_state = g_browser_process->local_state();
-  const base::Value::Dict& prefs_images =
-      local_state->GetDict(kUserImageProperties);
-  user_manager::User* user = GetUserAndModify();
-
-  const base::Value::Dict* image_properties =
-      prefs_images.FindDict(account_id_.GetUserEmail());
-
   // If the user image for `user_id` is managed by policy and the policy-set
   // image is being loaded and persisted right now, let that job continue. It
   // will update the user image when done.
   if (IsUserImageManaged() && job_.get())
     return;
 
+  const base::Value::Dict* image_properties = GetImageProperties();
   if (!image_properties) {
     SetInitialUserImage();
     return;
@@ -595,6 +580,7 @@
   const std::string* image_path =
       image_properties->FindString(kImagePathNodeName);
 
+  user_manager::User* user = GetUserAndModify();
   user->SetImageURL(image_url);
   user->SetStubImage(
       std::make_unique<user_manager::UserImage>(
@@ -986,6 +972,17 @@
   }
 }
 
+const base::Value::Dict* UserImageManagerImpl::GetImageProperties() {
+  PrefService* local_state = g_browser_process->local_state();
+  const base::Value::Dict& prefs_images =
+      local_state->GetDict(kUserImageProperties);
+
+  const base::Value::Dict* image_properties =
+      prefs_images.FindDict(account_id_.GetUserEmail());
+
+  return image_properties;
+}
+
 const user_manager::User* UserImageManagerImpl::GetUser() const {
   return user_manager_->FindUser(account_id_);
 }
diff --git a/chrome/browser/ash/login/users/avatar/user_image_manager_impl.h b/chrome/browser/ash/login/users/avatar/user_image_manager_impl.h
index b5be3fe..985d14b1 100644
--- a/chrome/browser/ash/login/users/avatar/user_image_manager_impl.h
+++ b/chrome/browser/ash/login/users/avatar/user_image_manager_impl.h
@@ -13,6 +13,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "base/timer/timer.h"
+#include "base/values.h"
 #include "chrome/browser/ash/login/users/avatar/user_image_manager.h"
 #include "chrome/browser/profiles/profile_downloader_delegate.h"
 #include "components/user_manager/user.h"
@@ -147,6 +148,9 @@
   // allowed to be synced and no sync observer exists yet.
   void TryToCreateImageSyncObserver();
 
+  // Returns the image properties for the user's user image.
+  const base::Value::Dict* GetImageProperties();
+
   // Returns immutable version of user with `user_id_`.
   const user_manager::User* GetUser() const;
 
diff --git a/chrome/browser/ash/phonehub/phone_hub_manager_factory.cc b/chrome/browser/ash/phonehub/phone_hub_manager_factory.cc
index bdea2303..13c9f992 100644
--- a/chrome/browser/ash/phonehub/phone_hub_manager_factory.cc
+++ b/chrome/browser/ash/phonehub/phone_hub_manager_factory.cc
@@ -29,7 +29,7 @@
 #include "chrome/browser/sync/session_sync_service_factory.h"
 #include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/ash/holding_space/holding_space_keyed_service_factory.h"
-#include "chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.h"
+#include "chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_dialog.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 
 namespace ash {
diff --git a/chrome/browser/ash/policy/status_collector/device_status_collector.cc b/chrome/browser/ash/policy/status_collector/device_status_collector.cc
index a15bedd..f726b9f 100644
--- a/chrome/browser/ash/policy/status_collector/device_status_collector.cc
+++ b/chrome/browser/ash/policy/status_collector/device_status_collector.cc
@@ -1518,7 +1518,7 @@
       return;
     }
     response_params_.device_status->set_root_device_total_storage_bytes(
-        chromeos::settings::RoundByteSize(root_device_size.value()));
+        ash::settings::RoundByteSize(root_device_size.value()));
     SetDeviceStatusReported();
   }
 
diff --git a/chrome/browser/ash/sync/os_sync_util.cc b/chrome/browser/ash/sync/os_sync_util.cc
index 2f9044a..c5ac025 100644
--- a/chrome/browser/ash/sync/os_sync_util.cc
+++ b/chrome/browser/ash/sync/os_sync_util.cc
@@ -36,8 +36,7 @@
     // app).
     bool sync_wallpaper =
         sync_apps && prefs->GetBoolean(syncer::prefs::kSyncThemes);
-    prefs->SetBoolean(chromeos::settings::prefs::kSyncOsWallpaper,
-                      sync_wallpaper);
+    prefs->SetBoolean(ash::settings::prefs::kSyncOsWallpaper, sync_wallpaper);
     prefs->SetBoolean(syncer::prefs::kOsSyncPrefsMigrated, true);
     migrated_this_time = true;
   }
diff --git a/chrome/browser/ash/sync/os_sync_util_unittest.cc b/chrome/browser/ash/sync/os_sync_util_unittest.cc
index e32a4e4..3d8c8be 100644
--- a/chrome/browser/ash/sync/os_sync_util_unittest.cc
+++ b/chrome/browser/ash/sync/os_sync_util_unittest.cc
@@ -13,7 +13,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace sp = syncer::prefs;
-namespace csp = chromeos::settings::prefs;
+namespace csp = ::ash::settings::prefs;
 
 class OsSyncUtilTest : public testing::Test {
  public:
diff --git a/chrome/browser/chrome_browser_interface_binders.cc b/chrome/browser/chrome_browser_interface_binders.cc
index d5e9487..a17ee4a 100644
--- a/chrome/browser/chrome_browser_interface_binders.cc
+++ b/chrome/browser/chrome_browser_interface_binders.cc
@@ -268,13 +268,13 @@
 #include "chrome/browser/ui/webui/ash/in_session_password_change/lock_screen_network_ui.h"
 #include "chrome/browser/ui/webui/ash/launcher_internals/launcher_internals.mojom.h"
 #include "chrome/browser/ui/webui/ash/launcher_internals/launcher_internals_ui.h"
+#include "chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_dialog.h"
 #include "chrome/browser/ui/webui/chromeos/bluetooth_pairing_dialog.h"
 #include "chrome/browser/ui/webui/chromeos/internet_config_dialog.h"
 #include "chrome/browser/ui/webui/chromeos/internet_detail_dialog.h"
 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
 #include "chrome/browser/ui/webui/chromeos/manage_mirrorsync/manage_mirrorsync.mojom.h"
 #include "chrome/browser/ui/webui/chromeos/manage_mirrorsync/manage_mirrorsync_ui.h"
-#include "chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.h"
 #include "chrome/browser/ui/webui/chromeos/network_ui.h"
 #include "chrome/browser/ui/webui/chromeos/parent_access/parent_access_ui.h"
 #include "chrome/browser/ui/webui/chromeos/parent_access/parent_access_ui.mojom.h"
@@ -1100,7 +1100,7 @@
   RegisterWebUIControllerInterfaceBinder<
       ash::multidevice_setup::mojom::MultiDeviceSetup, chromeos::OobeUI,
       ash::multidevice::ProximityAuthUI,
-      chromeos::multidevice_setup::MultiDeviceSetupDialogUI>(map);
+      ash::multidevice_setup::MultiDeviceSetupDialogUI>(map);
 
   RegisterWebUIControllerInterfaceBinder<
       parent_access_ui::mojom::ParentAccessUIHandler, chromeos::ParentAccessUI>(
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 3038bbd2..1d69e00 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -60,6 +60,7 @@
 #include "chrome/browser/extensions/chrome_extension_cookies.h"
 #include "chrome/browser/external_protocol/external_protocol_handler.h"
 #include "chrome/browser/favicon/favicon_utils.h"
+#include "chrome/browser/first_party_sets/first_party_sets_navigation_throttle.h"
 #include "chrome/browser/font_family_cache.h"
 #include "chrome/browser/gpu/chrome_browser_main_extra_parts_gpu.h"
 #include "chrome/browser/hid/chrome_hid_delegate.h"
@@ -232,6 +233,7 @@
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 #include "components/prefs/scoped_user_pref_update.h"
+#include "components/privacy_sandbox/privacy_sandbox_prefs.h"
 #include "components/privacy_sandbox/privacy_sandbox_settings.h"
 #include "components/safe_browsing/buildflags.h"
 #include "components/safe_browsing/content/browser/browser_url_loader_throttle.h"
@@ -4788,6 +4790,15 @@
 #if !BUILDFLAG(IS_ANDROID)
   MaybeAddThrottle(MaybeCreateAboutThisSiteThrottleFor(handle), &throttles);
 #endif
+
+  if (profile && profile->GetPrefs() &&
+      profile->GetPrefs()->GetBoolean(
+          prefs::kPrivacySandboxFirstPartySetsEnabled) &&
+      base::FeatureList::IsEnabled(features::kFirstPartySets)) {
+    MaybeAddThrottle(first_party_sets::FirstPartySetsNavigationThrottle::
+                         MaybeCreateNavigationThrottle(handle),
+                     &throttles);
+  }
   return throttles;
 }
 
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 00928c6..f8ba53d 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -92,9 +92,6 @@
     "//ash/services/device_sync",
     "//ash/services/device_sync:stub_device_sync",
     "//ash/services/device_sync/public/cpp",
-    "//ash/services/ime:constants",
-    "//ash/services/ime/public/cpp:structs",
-    "//ash/services/ime/public/mojom",
     "//ash/services/multidevice_setup",
     "//ash/services/multidevice_setup/public/cpp",
     "//ash/services/multidevice_setup/public/cpp:android_sms_app_helper_delegate",
@@ -328,6 +325,9 @@
     "//chromeos/ash/services/cros_healthd/private/cpp",
     "//chromeos/ash/services/cros_healthd/public/cpp",
     "//chromeos/ash/services/cros_healthd/public/mojom",
+    "//chromeos/ash/services/ime:constants",
+    "//chromeos/ash/services/ime/public/cpp:structs",
+    "//chromeos/ash/services/ime/public/mojom",
     "//chromeos/ash/services/nearby/public/cpp",
     "//chromeos/ash/services/nearby/public/mojom",
     "//chromeos/ash/services/quick_pair/public/mojom",
@@ -1077,7 +1077,6 @@
   deps = [
     ":chromeos",
     "//ash/constants",
-    "//ash/services/ime:test_support",
     "//ash/services/multidevice_setup/public/cpp:test_support",
     "//ash/webui/personalization_app/mojom",
     "//chrome/browser:browser_process",
@@ -1106,6 +1105,7 @@
     "//chromeos/ash/components/drivefs:test_support",
     "//chromeos/ash/components/login/auth",
     "//chromeos/ash/components/settings",
+    "//chromeos/ash/services/ime:test_support",
     "//chromeos/printing",
     "//chromeos/system",
     "//components/crx_file",
@@ -1496,6 +1496,7 @@
     "../ash/input_method/input_method_settings_unittest.cc",
     "../ash/input_method/longpress_diacritics_suggester_unittest.cc",
     "../ash/input_method/multi_word_suggester_unittest.cc",
+    "../ash/input_method/native_input_method_engine_observer_unittest.cc",
     "../ash/input_method/native_input_method_engine_unittest.cc",
     "../ash/input_method/personal_info_suggester_unittest.cc",
     "../ash/input_method/suggestions_collector_unittest.cc",
diff --git a/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_apitest.cc b/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_apitest.cc
index fa94453..2c201c8 100644
--- a/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_apitest.cc
+++ b/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_apitest.cc
@@ -352,6 +352,13 @@
       << message_;
 }
 
+IN_PROC_BROWSER_TEST_F(FileSystemProviderServiceWorkerApiTest, AddWatcher) {
+  ASSERT_TRUE(RunExtensionTest(
+      "file_system_provider/service_worker/add_watcher",
+      {.extension_url = "test.html"}, {.load_as_component = true}))
+      << message_;
+}
+
 IN_PROC_BROWSER_TEST_F(FileSystemProviderServiceWorkerApiTest, BigFile) {
   ASSERT_TRUE(RunExtensionTest("file_system_provider/service_worker/big_file",
                                {.extension_url = "test.html"},
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn
index 6a58d64..dd0b5360 100644
--- a/chrome/browser/extensions/BUILD.gn
+++ b/chrome/browser/extensions/BUILD.gn
@@ -1142,7 +1142,6 @@
       "//ash/constants",
       "//ash/keyboard/ui:resources_grit_grit",
       "//ash/public/cpp",
-      "//ash/services/ime/public/mojom",
       "//ash/webui/camera_app_ui",
       "//ash/webui/camera_app_ui:mojo_bindings",
       "//ash/webui/file_manager/untrusted_resources:file_manager_untrusted_resources",
@@ -1174,6 +1173,7 @@
       "//chromeos/ash/services/assistant/public/cpp",
       "//chromeos/ash/services/chromebox_for_meetings/public/cpp",
       "//chromeos/ash/services/chromebox_for_meetings/public/mojom",
+      "//chromeos/ash/services/ime/public/mojom",
       "//chromeos/components/remote_apps/mojom",
       "//chromeos/login/login_state",
       "//chromeos/process_proxy",
diff --git a/chrome/browser/extensions/api/browsing_data/OWNERS b/chrome/browser/extensions/api/browsing_data/OWNERS
index 67f9a1c..26e3ab3a 100644
--- a/chrome/browser/extensions/api/browsing_data/OWNERS
+++ b/chrome/browser/extensions/api/browsing_data/OWNERS
@@ -1,4 +1,3 @@
 # Anyone in the parent directories can review changes to this directory,
 # but the following people are the most knowledgable:
 dullweber@chromium.org
-mkwst@chromium.org
diff --git a/chrome/browser/extensions/api/cookies/OWNERS b/chrome/browser/extensions/api/cookies/OWNERS
deleted file mode 100644
index 3f84563..0000000
--- a/chrome/browser/extensions/api/cookies/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-mkwst@chromium.org
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc
index b63cf0d..90cb9c7 100644
--- a/chrome/browser/extensions/api/settings_private/prefs_util.cc
+++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -814,6 +814,8 @@
           settings_api::PrefType::PREF_TYPE_BOOLEAN;
   (*s_allowlist)[::ash::prefs::kPowerQuickDimEnabled] =
       settings_api::PrefType::PREF_TYPE_BOOLEAN;
+  (*s_allowlist)[::ash::prefs::kPowerQuickLockDelay] =
+      settings_api::PrefType::PREF_TYPE_NUMBER;
   (*s_allowlist)[ash::prefs::kUserCameraAllowed] =
       settings_api::PrefType::PREF_TYPE_BOOLEAN;
   (*s_allowlist)[ash::prefs::kUserMicrophoneAllowed] =
diff --git a/chrome/browser/extensions/chrome_extensions_browser_interface_binders.cc b/chrome/browser/extensions/chrome_extensions_browser_interface_binders.cc
index 5498b1cf1..53a3bb12 100644
--- a/chrome/browser/extensions/chrome_extensions_browser_interface_binders.cc
+++ b/chrome/browser/extensions/chrome_extensions_browser_interface_binders.cc
@@ -43,7 +43,7 @@
 #include "ui/accessibility/accessibility_features.h"
 
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
-#include "ash/services/ime/public/mojom/input_engine.mojom.h"
+#include "chromeos/ash/services/ime/public/mojom/input_engine.mojom.h"
 #include "chromeos/services/machine_learning/public/cpp/service_connection.h"  // nogncheck
 #include "ui/base/ime/ash/extension_ime_util.h"
 #include "ui/base/ime/ash/input_method_manager.h"
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedFeatures.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedFeatures.java
index 77a3a8b5..7b10e5b2 100644
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedFeatures.java
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedFeatures.java
@@ -19,6 +19,8 @@
 import org.chromium.components.user_prefs.UserPrefs;
 import org.chromium.ui.base.DeviceFormFactor;
 
+import java.util.concurrent.TimeUnit;
+
 /**
  * Helper methods covering more complex Feed related feature checks and states.
  */
@@ -29,6 +31,7 @@
     private static final String FEED_TAB_STICKYNESS_LOGIC_PARAM = "feed_tab_stickiness_logic";
     private static final String RESET_UPON_CHROME_RESTART = "reset_upon_chrome_restart";
     private static final String INDEFINITELY_PERSISTED = "indefinitely_persisted";
+    private static final long ONE_DAY_DELTA_MILLIS = TimeUnit.DAYS.toMillis(1L);
 
     private static PrefService sFakePrefServiceForTest;
     private static boolean sIsFirstFeedTabStickinessCheckSinceLaunch = true;
@@ -64,10 +67,47 @@
     }
 
     public static boolean shouldUseNewIndicator() {
-        return ChromeFeatureList
-                .getFieldTrialParamByFeature(
-                        ChromeFeatureList.WEB_FEED_AWARENESS, "awareness_style")
-                .equals("new_animation");
+        // Return true if we are not rate limited.
+        if (ChromeFeatureList
+                        .getFieldTrialParamByFeature(
+                                ChromeFeatureList.WEB_FEED_AWARENESS, "awareness_style")
+                        .equals("new_animation_no_limit")) {
+            return true;
+        }
+        // Otherwise, the rate limit is:
+        // 1. We have never seen the web feed.
+        // 2. It's been > 1 day since we last seen the new indicator.
+        if (ChromeFeatureList
+                        .getFieldTrialParamByFeature(
+                                ChromeFeatureList.WEB_FEED_AWARENESS, "awareness_style")
+                        .equals("new_animation")
+                && !getPrefService().getBoolean(Pref.HAS_SEEN_WEB_FEED)) {
+            String timestamp = getPrefService().getString(Pref.LAST_BADGE_ANIMATION_TIME);
+            long currentTime = System.currentTimeMillis();
+            long parsedTime;
+            try {
+                parsedTime = Long.parseLong(timestamp);
+            } catch (NumberFormatException e) {
+                parsedTime = 0L;
+            }
+            // Ignore parsed timestamps in the future.
+            return currentTime < parsedTime || currentTime - parsedTime > ONE_DAY_DELTA_MILLIS;
+        }
+        return false;
+    }
+
+    /**
+     * Updates the timestamp for the last time the new indicator was seen to now.
+     */
+    public static void updateNewIndicatorTimestamp() {
+        getPrefService().setString(Pref.LAST_BADGE_ANIMATION_TIME, "" + System.currentTimeMillis());
+    }
+
+    /**
+     * Updates that the following feed has been seen.
+     */
+    public static void updateFollowingFeedSeen() {
+        getPrefService().setBoolean(Pref.HAS_SEEN_WEB_FEED, true);
     }
 
     public static boolean isMultiColumnFeedEnabled(Context context) {
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedFeaturesTest.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedFeaturesTest.java
index 82f9a22..f7b3c4d 100644
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedFeaturesTest.java
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedFeaturesTest.java
@@ -5,6 +5,8 @@
 package org.chromium.chrome.browser.feed;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
@@ -28,6 +30,8 @@
 import org.chromium.chrome.browser.preferences.Pref;
 import org.chromium.components.prefs.PrefService;
 
+import java.time.Duration;
+
 /**
  * Unit tests for {@link FeedFeatures}.
  */
@@ -107,4 +111,68 @@
         assertEquals(StreamTabId.FOR_YOU, FeedFeatures.getFeedTabIdToRestore());
         assertEquals(StreamTabId.FOR_YOU, FeedFeatures.getFeedTabIdToRestore());
     }
+
+    @Test
+    public void testShouldUseNewIndicator_noLimit() {
+        mParamsTestValues.addFieldTrialParamOverride(
+                ChromeFeatureList.WEB_FEED_AWARENESS, "awareness_style", "new_animation_no_limit");
+        FeatureList.setTestValues(mParamsTestValues);
+
+        when(mPrefService.getBoolean(Pref.HAS_SEEN_WEB_FEED)).thenReturn(true);
+        when(mPrefService.getString(Pref.LAST_BADGE_ANIMATION_TIME))
+                .thenReturn("" + System.currentTimeMillis());
+
+        assertTrue(FeedFeatures.shouldUseNewIndicator());
+    }
+
+    @Test
+    public void testShouldUseNewIndicator_seenFeed() {
+        mParamsTestValues.addFieldTrialParamOverride(
+                ChromeFeatureList.WEB_FEED_AWARENESS, "awareness_style", "new_animation");
+        FeatureList.setTestValues(mParamsTestValues);
+
+        when(mPrefService.getBoolean(Pref.HAS_SEEN_WEB_FEED)).thenReturn(true);
+        when(mPrefService.getString(Pref.LAST_BADGE_ANIMATION_TIME)).thenReturn("0");
+
+        assertFalse(FeedFeatures.shouldUseNewIndicator());
+    }
+
+    @Test
+    public void testShouldUseNewIndicator_seenAnimation() {
+        mParamsTestValues.addFieldTrialParamOverride(
+                ChromeFeatureList.WEB_FEED_AWARENESS, "awareness_style", "new_animation");
+        FeatureList.setTestValues(mParamsTestValues);
+
+        when(mPrefService.getBoolean(Pref.HAS_SEEN_WEB_FEED)).thenReturn(false);
+        when(mPrefService.getString(Pref.LAST_BADGE_ANIMATION_TIME))
+                .thenReturn("" + System.currentTimeMillis());
+
+        assertFalse(FeedFeatures.shouldUseNewIndicator());
+    }
+
+    @Test
+    public void testShouldUseNewIndicator_notSeenFeedAndAnimation() {
+        mParamsTestValues.addFieldTrialParamOverride(
+                ChromeFeatureList.WEB_FEED_AWARENESS, "awareness_style", "new_animation");
+        FeatureList.setTestValues(mParamsTestValues);
+
+        when(mPrefService.getBoolean(Pref.HAS_SEEN_WEB_FEED)).thenReturn(false);
+        when(mPrefService.getString(Pref.LAST_BADGE_ANIMATION_TIME))
+                .thenReturn("" + (System.currentTimeMillis() - Duration.ofDays(1).toMillis()));
+
+        assertTrue(FeedFeatures.shouldUseNewIndicator());
+    }
+
+    @Test
+    public void testShouldUseNewIndicator_notSeenAnimationInFuture() {
+        mParamsTestValues.addFieldTrialParamOverride(
+                ChromeFeatureList.WEB_FEED_AWARENESS, "awareness_style", "new_animation");
+        FeatureList.setTestValues(mParamsTestValues);
+
+        when(mPrefService.getBoolean(Pref.HAS_SEEN_WEB_FEED)).thenReturn(false);
+        when(mPrefService.getString(Pref.LAST_BADGE_ANIMATION_TIME))
+                .thenReturn("" + (System.currentTimeMillis() + Duration.ofDays(1).toMillis()));
+
+        assertTrue(FeedFeatures.shouldUseNewIndicator());
+    }
 }
diff --git a/chrome/browser/first_party_sets/BUILD.gn b/chrome/browser/first_party_sets/BUILD.gn
index 7dbeb63..6037c75 100644
--- a/chrome/browser/first_party_sets/BUILD.gn
+++ b/chrome/browser/first_party_sets/BUILD.gn
@@ -13,6 +13,8 @@
     "//chrome/test:*",
   ]
   sources = [
+    "first_party_sets_navigation_throttle.cc",
+    "first_party_sets_navigation_throttle.h",
     "first_party_sets_overrides_policy_handler.cc",
     "first_party_sets_overrides_policy_handler.h",
     "first_party_sets_policy_service.cc",
diff --git a/chrome/browser/first_party_sets/first_party_sets_navigation_throttle.cc b/chrome/browser/first_party_sets/first_party_sets_navigation_throttle.cc
new file mode 100644
index 0000000..af86e36
--- /dev/null
+++ b/chrome/browser/first_party_sets/first_party_sets_navigation_throttle.cc
@@ -0,0 +1,63 @@
+// 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.
+
+#include "chrome/browser/first_party_sets/first_party_sets_navigation_throttle.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/bind.h"
+#include "chrome/browser/first_party_sets/first_party_sets_policy_service.h"
+#include "chrome/browser/first_party_sets/first_party_sets_policy_service_factory.h"
+#include "chrome/browser/profiles/profile.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/navigation_handle.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/common/content_features.h"
+
+namespace first_party_sets {
+
+namespace {
+
+using ThrottleCheckResult = content::NavigationThrottle::ThrottleCheckResult;
+
+}  // namespace
+
+FirstPartySetsNavigationThrottle::FirstPartySetsNavigationThrottle(
+    content::NavigationHandle* navigation_handle)
+    : content::NavigationThrottle(navigation_handle),
+      profile_(*Profile::FromBrowserContext(
+          navigation_handle->GetWebContents()->GetBrowserContext())) {}
+
+FirstPartySetsNavigationThrottle::~FirstPartySetsNavigationThrottle() = default;
+
+ThrottleCheckResult FirstPartySetsNavigationThrottle::WillStartRequest() {
+  FirstPartySetsPolicyService* service =
+      FirstPartySetsPolicyServiceFactory::GetForBrowserContext(&profile_);
+  // FirstPartySetsPolicyService is always created.
+  DCHECK(service);
+  if (!service->is_ready()) {
+    service->RegisterThrottleResumeCallback(base::BindOnce(
+        &FirstPartySetsNavigationThrottle::Resume, weak_factory_.GetWeakPtr()));
+    return content::NavigationThrottle::DEFER;
+  }
+  return content::NavigationThrottle::PROCEED;
+}
+
+const char* FirstPartySetsNavigationThrottle::GetNameForLogging() {
+  return "FirstPartySetsNavigationThrottle";
+}
+
+std::unique_ptr<FirstPartySetsNavigationThrottle>
+FirstPartySetsNavigationThrottle::MaybeCreateNavigationThrottle(
+    content::NavigationHandle* navigation_handle) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  if (!features::kFirstPartySetsClearSiteDataOnChangedSets.Get() ||
+      navigation_handle->GetParentFrameOrOuterDocument()) {
+    return nullptr;
+  }
+  return std::make_unique<FirstPartySetsNavigationThrottle>(navigation_handle);
+}
+
+}  // namespace first_party_sets
diff --git a/chrome/browser/first_party_sets/first_party_sets_navigation_throttle.h b/chrome/browser/first_party_sets/first_party_sets_navigation_throttle.h
new file mode 100644
index 0000000..780439d
--- /dev/null
+++ b/chrome/browser/first_party_sets/first_party_sets_navigation_throttle.h
@@ -0,0 +1,46 @@
+// 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.
+
+#ifndef CHROME_BROWSER_FIRST_PARTY_SETS_FIRST_PARTY_SETS_NAVIGATION_THROTTLE_H_
+#define CHROME_BROWSER_FIRST_PARTY_SETS_FIRST_PARTY_SETS_NAVIGATION_THROTTLE_H_
+
+#include <memory>
+
+#include "base/memory/raw_ref.h"
+#include "base/memory/weak_ptr.h"
+#include "content/public/browser/navigation_throttle.h"
+
+namespace content {
+class NavigationHandle;
+}  // namespace content
+
+class Profile;
+
+namespace first_party_sets {
+
+// Observes navigations and defers navigations of outermost frames on
+// First-Party Sets initialization during startup.
+class FirstPartySetsNavigationThrottle : public content::NavigationThrottle {
+ public:
+  explicit FirstPartySetsNavigationThrottle(content::NavigationHandle* handle);
+  ~FirstPartySetsNavigationThrottle() override;
+
+  // content::NavigationThrottle:
+  ThrottleCheckResult WillStartRequest() override;
+  const char* GetNameForLogging() override;
+
+  // Only create throttle if FPS clearing is enabled and this is the outermost
+  // frame navigation; returns nullptr otherwise.
+  static std::unique_ptr<FirstPartySetsNavigationThrottle>
+  MaybeCreateNavigationThrottle(content::NavigationHandle* navigation_handle);
+
+ private:
+  raw_ref<Profile> profile_;
+
+  base::WeakPtrFactory<FirstPartySetsNavigationThrottle> weak_factory_{this};
+};
+
+}  // namespace first_party_sets
+
+#endif  // CHROME_BROWSER_FIRST_PARTY_SETS_FIRST_PARTY_SETS_NAVIGATION_THROTTLE_H_
diff --git a/chrome/browser/first_party_sets/first_party_sets_navigation_throttle_unittest.cc b/chrome/browser/first_party_sets/first_party_sets_navigation_throttle_unittest.cc
new file mode 100644
index 0000000..916cf22
--- /dev/null
+++ b/chrome/browser/first_party_sets/first_party_sets_navigation_throttle_unittest.cc
@@ -0,0 +1,94 @@
+// 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.
+
+#include "chrome/browser/first_party_sets/first_party_sets_navigation_throttle.h"
+
+#include "base/test/scoped_feature_list.h"
+#include "chrome/test/base/chrome_render_view_host_test_harness.h"
+#include "content/public/common/content_features.h"
+#include "content/public/test/mock_navigation_handle.h"
+
+namespace {
+
+const char kExampleURL[] = "https://example.com";
+
+}  // namespace
+
+namespace first_party_sets {
+
+class FirstPartySetsNavigationThrottleTest
+    : public ChromeRenderViewHostTestHarness {
+ public:
+  FirstPartySetsNavigationThrottleTest() {
+    features_.InitAndEnableFeatureWithParameters(
+        features::kFirstPartySets,
+        {{features::kFirstPartySetsClearSiteDataOnChangedSets.name, "true"}});
+  }
+
+  void SetUp() override {
+    ChromeRenderViewHostTestHarness::SetUp();
+
+    content::RenderFrameHostTester::For(main_rfh())
+        ->InitializeRenderFrameIfNeeded();
+    subframe_ = content::RenderFrameHostTester::For(main_rfh())
+                    ->AppendChild("subframe");
+  }
+
+  content::RenderFrameHost* subframe() { return subframe_; }
+
+ private:
+  base::test::ScopedFeatureList features_;
+  raw_ptr<content::RenderFrameHost> subframe_;
+};
+
+TEST_F(FirstPartySetsNavigationThrottleTest,
+       MaybeCreateNavigationThrottle_ClearingFeatureDisabled) {
+  base::test::ScopedFeatureList features;
+  features.InitAndEnableFeatureWithParameters(
+      features::kFirstPartySets,
+      {{features::kFirstPartySetsClearSiteDataOnChangedSets.name, "false"}});
+
+  content::MockNavigationHandle handle(GURL(kExampleURL), main_rfh());
+  ASSERT_TRUE(handle.IsInOutermostMainFrame());
+
+  EXPECT_FALSE(
+      FirstPartySetsNavigationThrottle::MaybeCreateNavigationThrottle(&handle));
+}
+
+TEST_F(FirstPartySetsNavigationThrottleTest,
+       MaybeCreateNavigationThrottle_ClearingFeatureEnabled) {
+  content::MockNavigationHandle handle(GURL(kExampleURL), main_rfh());
+  ASSERT_TRUE(handle.IsInOutermostMainFrame());
+
+  EXPECT_TRUE(
+      FirstPartySetsNavigationThrottle::MaybeCreateNavigationThrottle(&handle));
+}
+
+TEST_F(FirstPartySetsNavigationThrottleTest,
+       MaybeCreateNavigationThrottle_OnlyCreateForOuterMostframes) {
+  // Create throttle for main frames.
+  content::MockNavigationHandle handle(GURL(kExampleURL), main_rfh());
+  ASSERT_TRUE(handle.IsInOutermostMainFrame());
+  EXPECT_TRUE(
+      FirstPartySetsNavigationThrottle::MaybeCreateNavigationThrottle(&handle));
+
+  // Never create throttle for subframes.
+  handle.set_render_frame_host(subframe());
+  ASSERT_FALSE(handle.IsInOutermostMainFrame());
+  EXPECT_FALSE(
+      FirstPartySetsNavigationThrottle::MaybeCreateNavigationThrottle(&handle));
+}
+
+TEST_F(FirstPartySetsNavigationThrottleTest, WillStartRequest_Defer) {
+  // Create throttle for main frames.
+  content::MockNavigationHandle handle(GURL(kExampleURL), main_rfh());
+  ASSERT_TRUE(handle.IsInOutermostMainFrame());
+  auto throttle =
+      FirstPartySetsNavigationThrottle::MaybeCreateNavigationThrottle(&handle);
+  EXPECT_TRUE(throttle);
+  EXPECT_EQ(content::NavigationThrottle::DEFER,
+            throttle->WillStartRequest().action());
+}
+
+}  // namespace first_party_sets
diff --git a/chrome/browser/first_party_sets/first_party_sets_policy_service.cc b/chrome/browser/first_party_sets/first_party_sets_policy_service.cc
index 7488835..3a31fb6 100644
--- a/chrome/browser/first_party_sets/first_party_sets_policy_service.cc
+++ b/chrome/browser/first_party_sets/first_party_sets_policy_service.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <utility>
+
 #include "chrome/browser/first_party_sets/first_party_sets_policy_service.h"
 
 #include "base/feature_list.h"
@@ -128,9 +130,20 @@
   }
 }
 
+void FirstPartySetsPolicyService::RegisterThrottleResumeCallback(
+    base::OnceClosure resume_callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  if (is_ready()) {
+    std::move(resume_callback).Run();
+    return;
+  }
+  on_ready_callbacks_.push_back(std::move(resume_callback));
+}
+
 void FirstPartySetsPolicyService::Shutdown() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   access_delegates_.Clear();
+  on_ready_callbacks_.clear();
   browser_context_ = nullptr;
   weak_factory_.InvalidateWeakPtrs();
 }
@@ -221,6 +234,14 @@
         MakeReadyEvent(config_.value().Clone(), cache_filter_.value().Clone()));
   }
 
+  base::circular_deque<base::OnceClosure> callback_queue;
+  callback_queue.swap(on_ready_callbacks_);
+  while (!callback_queue.empty()) {
+    base::OnceClosure callback = std::move(callback_queue.front());
+    callback_queue.pop_front();
+    std::move(callback).Run();
+  }
+
   if (on_first_init_complete_for_testing_.has_value()) {
     std::move(on_first_init_complete_for_testing_).value().Run();
   }
@@ -229,6 +250,7 @@
 void FirstPartySetsPolicyService::ResetForTesting() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   access_delegates_.Clear();
+  on_ready_callbacks_.clear();
   config_.reset();
   cache_filter_.reset();
   on_first_init_complete_for_testing_.reset();
diff --git a/chrome/browser/first_party_sets/first_party_sets_policy_service.h b/chrome/browser/first_party_sets/first_party_sets_policy_service.h
index 93370f8f..c7a9ede 100644
--- a/chrome/browser/first_party_sets/first_party_sets_policy_service.h
+++ b/chrome/browser/first_party_sets/first_party_sets_policy_service.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_FIRST_PARTY_SETS_FIRST_PARTY_SETS_POLICY_SERVICE_H_
 #define CHROME_BROWSER_FIRST_PARTY_SETS_FIRST_PARTY_SETS_POLICY_SERVICE_H_
 
+#include "base/containers/circular_deque.h"
 #include "base/memory/raw_ptr.h"
 #include "base/sequence_checker.h"
 #include "base/thread_annotations.h"
@@ -59,6 +60,11 @@
   // First-Party Sets enabled pref changes.
   void OnFirstPartySetsEnabledChanged(bool enabled);
 
+  // Invoke the callback synchronously to resume navigation if the instance is
+  // ready; or stores the callback to be invoked when this service is ready to
+  // do so.
+  void RegisterThrottleResumeCallback(base::OnceClosure resume_callback);
+
   // KeyedService:
   void Shutdown() override;
 
@@ -81,6 +87,13 @@
                base::OnceCallback<void(net::FirstPartySetsContextConfig)>)>
           get_config);
 
+  // Returns true when this instance has received the config thus has been fully
+  // initialized.
+  bool is_ready() const {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    return config_.has_value();
+  }
+
   void ResetForTesting();
 
   // Looks up `site` in Chrome's list of First-Party Sets and returns its
@@ -144,6 +157,10 @@
   absl::optional<net::FirstPartySetsCacheFilter> cache_filter_
       GUARDED_BY_CONTEXT(sequence_checker_);
 
+  // The queue of callbacks that are waiting for the instance to be initialized.
+  base::circular_deque<base::OnceClosure> on_ready_callbacks_
+      GUARDED_BY_CONTEXT(sequence_checker_);
+
   // Callback used by tests to wait for the ctor's initialization flow to
   // complete.
   absl::optional<base::OnceClosure> on_first_init_complete_for_testing_;
diff --git a/chrome/browser/first_party_sets/first_party_sets_policy_service_unittest.cc b/chrome/browser/first_party_sets/first_party_sets_policy_service_unittest.cc
index 7b5a312..9247351d 100644
--- a/chrome/browser/first_party_sets/first_party_sets_policy_service_unittest.cc
+++ b/chrome/browser/first_party_sets/first_party_sets_policy_service_unittest.cc
@@ -489,4 +489,59 @@
   env().RunUntilIdle();
 }
 
+namespace {
+
+enum PrefState { kDefault, kDisabled, kEnabled };
+
+}  // namespace
+
+class FirstPartySetsPolicyServiceResumeThrottleTest
+    : public FirstPartySetsPolicyServiceTest,
+      public ::testing::WithParamInterface<std::tuple<bool, bool, PrefState>> {
+ public:
+  FirstPartySetsPolicyServiceResumeThrottleTest() {
+    if (IsFeatureEnabled()) {
+      features_.InitAndEnableFeatureWithParameters(
+          features::kFirstPartySets,
+          {{features::kFirstPartySetsClearSiteDataOnChangedSets.name,
+            IsClearingFeatureEnabled() ? "true" : "false"}});
+    } else {
+      features_.InitAndDisableFeature(features::kFirstPartySets);
+    }
+  }
+
+  bool IsPrefEnabled() { return GetPrefState() == PrefState::kEnabled; }
+
+ private:
+  bool IsFeatureEnabled() { return std::get<0>(GetParam()); }
+  bool IsClearingFeatureEnabled() { return std::get<1>(GetParam()); }
+  PrefState GetPrefState() { return std::get<2>(GetParam()); }
+
+  base::test::ScopedFeatureList features_;
+};
+
+// Verify the throttle resume callback is always invoked.
+TEST_P(FirstPartySetsPolicyServiceResumeThrottleTest,
+       MaybeAddNavigationThrottleResumeCallback) {
+  profile()->GetPrefs()->SetBoolean(prefs::kPrivacySandboxFirstPartySetsEnabled,
+                                    IsPrefEnabled());
+  base::RunLoop run_loop;
+  service()->RegisterThrottleResumeCallback(run_loop.QuitClosure());
+  service()->InitForTesting(
+      [&](PrefService* prefs,
+          base::OnceCallback<void(net::FirstPartySetsContextConfig)> callback) {
+        std::move(callback).Run(net::FirstPartySetsContextConfig());
+      });
+  run_loop.Run();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    All,
+    FirstPartySetsPolicyServiceResumeThrottleTest,
+    ::testing::Combine(::testing::Bool(),
+                       ::testing::Bool(),
+                       ::testing::Values(PrefState::kDefault,
+                                         PrefState::kDisabled,
+                                         PrefState::kEnabled)));
+
 }  // namespace first_party_sets
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index d6df92d..7ca529f 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -997,11 +997,6 @@
     "expiry_milestone": 98
   },
   {
-    "name": "clean-undecryptable-passwords",
-    "owners": [ "derinel@google.com", "mamir" ],
-    "expiry_milestone": 108
-  },
-  {
     "name": "clear-cross-site-cross-browsing-context-group-window-name",
     "owners": [ "shuuran", "kaustubhag" ],
     "expiry_milestone": 110
@@ -2335,7 +2330,7 @@
   },
   {
     "name": "enable-feed-position-on-ntp",
-    "owners": ["clank-start","hanxi","spdonghao", "andrewheard"],
+    "owners": ["clank-start","hanxi"],
     "expiry_milestone": 110
   },
   {
@@ -2967,7 +2962,7 @@
   },
   {
     "name": "enable-search-resumption-module",
-    "owners": ["clank-start","hanxi","spdonghao", "andrewheard"],
+    "owners": ["clank-start","hanxi"],
     "expiry_milestone": 110
   },
   {
@@ -2998,7 +2993,7 @@
   },
   {
     "name": "enable-show-scrollable-mvt-on-ntp",
-    "owners": ["clank-start","hanxi","spdonghao"],
+    "owners": ["clank-start","hanxi"],
     "expiry_milestone": 110
   },
   {
@@ -3024,12 +3019,12 @@
   },
   {
     "name": "enable-start-surface-disabled-feed-improvement",
-    "owners": [ "hanxi", "spdonghao" ],
+    "owners": [ "hanxi", "clank-start" ],
     "expiry_milestone": 115
   },
   {
     "name": "enable-start-surface-refactor",
-    "owners": [ "hanxi", "spdonghao" ],
+    "owners": [ "hanxi", "clank-start" ],
     "expiry_milestone": 115
   },
   {
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 1fedefc..705a2b9 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -6642,11 +6642,6 @@
 #endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX)
 
 #if BUILDFLAG(IS_LINUX)
-const char kCleanUndecryptablePasswordsLinuxName[] =
-    "Cleanup local undecryptable passwords during initial sync flow";
-const char kCleanUndecryptablePasswordsLinuxDescription[] =
-    "Deletes the undecryptable passwords from the local database to enable "
-    "syncing all passwords during the initial sync.";
 const char kForcePasswordInitialSyncWhenDecryptionFailsName[] =
     "Force initial sync to clean local undecryptable passwords during startup";
 const char kForcePasswordInitialSyncWhenDecryptionFailsDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 99c5223..c568c76 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -3802,9 +3802,6 @@
 extern const char kOzonePlatformHintName[];
 extern const char kOzonePlatformHintDescription[];
 
-extern const char kCleanUndecryptablePasswordsLinuxName[];
-extern const char kCleanUndecryptablePasswordsLinuxDescription[];
-
 extern const char kForcePasswordInitialSyncWhenDecryptionFailsName[];
 extern const char kForcePasswordInitialSyncWhenDecryptionFailsDescription[];
 #endif  // BUILDFLAG(IS_LINUX)
diff --git a/chrome/browser/password_manager/account_password_store_factory.cc b/chrome/browser/password_manager/account_password_store_factory.cc
index 007463c..66b54b3c 100644
--- a/chrome/browser/password_manager/account_password_store_factory.cc
+++ b/chrome/browser/password_manager/account_password_store_factory.cc
@@ -14,6 +14,7 @@
 #include "base/memory/weak_ptr.h"
 #include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/password_manager/chrome_password_manager_client.h"
 #include "chrome/browser/password_manager/credentials_cleaner_runner_factory.h"
 #include "chrome/browser/password_manager/password_reuse_manager_factory.h"
 #include "chrome/browser/password_manager/password_store_utils.h"
@@ -36,16 +37,16 @@
 #include "content/public/browser/storage_partition.h"
 #include "content/public/browser/web_contents.h"
 
-#if !BUILDFLAG(IS_ANDROID)
-#include "base/task/task_traits.h"
-#include "chrome/browser/password_manager/chrome_password_manager_client.h"
+#if BUILDFLAG(IS_ANDROID)
+#include "chrome/browser/ui/android/tab_model/tab_model.h"
+#include "chrome/browser/ui/android/tab_model/tab_model_list.h"
+#else
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "content/public/browser/browser_task_traits.h"
-#endif  // !BUILDFLAG(IS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 
 using password_manager::PasswordStore;
 using password_manager::PasswordStoreInterface;
@@ -54,11 +55,17 @@
 namespace {
 
 void SyncEnabledOrDisabled(Profile* profile) {
-#if BUILDFLAG(IS_ANDROID)
-  NOTREACHED();
-#else
   // Update all form managers. Incognito tabs originated from this profile
   // can also fill passwords, so they should be included.
+#if BUILDFLAG(IS_ANDROID)
+  for (TabModel* tab_model : TabModelList::models()) {
+    for (int index = 0; index < tab_model->GetTabCount(); index++) {
+      content::WebContents* web_contents = tab_model->GetWebContentsAt(index);
+      ChromePasswordManagerClient::FromWebContents(web_contents)
+          ->UpdateFormManagers();
+    }
+  }
+#else
   for (Browser* browser : *BrowserList::GetInstance()) {
     if (browser->profile()->GetOriginalProfile() !=
         profile->GetOriginalProfile()) {
@@ -71,11 +78,12 @@
           ->UpdateFormManagers();
     }
   }
+#endif  // BUILDFLAG(IS_ANDROID)
+
   password_manager::PasswordReuseManager* reuse_manager =
       PasswordReuseManagerFactory::GetForProfile(profile);
   if (reuse_manager)
     reuse_manager->AccountStoreStateChanged();
-#endif  // BUILDFLAG(IS_ANDROID)
 }
 
 #if !BUILDFLAG(IS_ANDROID)
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
index 05cb807..a97c2896 100644
--- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -689,9 +689,6 @@
   { key::kSetTimeoutWithout1MsClampEnabled,
     policy_prefs::kSetTimeoutWithout1MsClampEnabled,
     base::Value::Type::BOOLEAN },
-  { key::kUnthrottledNestedTimeoutEnabled,
-    policy_prefs::kUnthrottledNestedTimeoutEnabled,
-    base::Value::Type::BOOLEAN },
   { key::kDefaultCookiesSetting,
     prefs::kManagedDefaultCookiesSetting,
     base::Value::Type::INTEGER },
diff --git a/chrome/browser/policy/messaging_layer/upload/record_handler_impl.cc b/chrome/browser/policy/messaging_layer/upload/record_handler_impl.cc
index 300ed05d..a222921 100644
--- a/chrome/browser/policy/messaging_layer/upload/record_handler_impl.cc
+++ b/chrome/browser/policy/messaging_layer/upload/record_handler_impl.cc
@@ -84,7 +84,8 @@
   ~ReportUploader() override;
 
   void OnStart() override;
-  void OnCompletion() override;
+  void OnCompletion(
+      const DmServerUploadService::CompletionResponse& result) override;
 
   void StartUpload();
   void OnUploadComplete(StatusOr<base::Value::Dict> response);
@@ -200,7 +201,8 @@
           std::move(request_result.value()), std::move(response_cb)));
 }
 
-void RecordHandlerImpl::ReportUploader::OnCompletion() {
+void RecordHandlerImpl::ReportUploader::OnCompletion(
+    const DmServerUploadService::CompletionResponse& result) {
   // In case |OnUploadComplete| was skipped for whatever reason.
   ScopedReservation release(std::move(scoped_reservation_));
 }
diff --git a/chrome/browser/policy/test/unthrottled_nested_timeout_policy_browsertest.cc b/chrome/browser/policy/test/unthrottled_nested_timeout_policy_browsertest.cc
index afbbcf5..50d645b 100644
--- a/chrome/browser/policy/test/unthrottled_nested_timeout_policy_browsertest.cc
+++ b/chrome/browser/policy/test/unthrottled_nested_timeout_policy_browsertest.cc
@@ -24,6 +24,8 @@
 
 namespace policy {
 
+// TODO(crbug.com/1374567): Re-enable or delete this test.
+#if 0
 class PolicyTestUnthrottledNestedTimeout : public PolicyTest {
  protected:
   void SetUpInProcessBrowserTestFixture() override {
@@ -69,5 +71,6 @@
   EXPECT_TRUE(message_queue.WaitForMessage(&message));
   EXPECT_EQ("true", message);
 }
+#endif
 
 }  // namespace policy
diff --git a/chrome/browser/privacy_budget/privacy_budget_browsertest.cc b/chrome/browser/privacy_budget/privacy_budget_browsertest.cc
index a2bacc9..dca1c51a 100644
--- a/chrome/browser/privacy_budget/privacy_budget_browsertest.cc
+++ b/chrome/browser/privacy_budget/privacy_budget_browsertest.cc
@@ -164,7 +164,6 @@
 
 IN_PROC_BROWSER_TEST_P(PrivacyBudgetBrowserTestWithTestRecorder,
                        RecordingFeaturesCalledInWorker) {
-  const auto file_path = GetParam();
   ASSERT_TRUE(embedded_test_server()->Start());
 
   content::DOMMessageQueue messages(web_contents());
@@ -185,7 +184,7 @@
                                    base::BindLambdaForTesting(quit_run_loop));
 
   ASSERT_TRUE(content::NavigateToURL(
-      web_contents(), embedded_test_server()->GetURL(file_path)));
+      web_contents(), embedded_test_server()->GetURL(FilePathXYZ())));
 
   // The document calls a bunch of instrumented functions and sends a message
   // back to the test. Receipt of the message indicates that the script
@@ -196,6 +195,11 @@
   // Wait for the metrics to come down the pipe.
   run_loop.Run();
 
+  // The previously registered callback will be invalid after the test class is
+  // destructed.
+  recorder().SetOnAddEntryCallback(ukm::builders::Identifiability::kEntryName,
+                                   {});
+
   // Test succeeds if there is no timeout. However, let's recheck the metrics
   // here, so that if there is a timeout we get an output of which metrics are
   // missing.
@@ -212,6 +216,140 @@
 #endif
                       "/privacy_budget/calls_service_worker.html"));
 
+namespace {
+
+using PrivacyBudgetBrowserTestForWorkersClientAdded =
+    PrivacyBudgetBrowserTestWithTestRecorder;
+}  // namespace
+
+IN_PROC_BROWSER_TEST_P(PrivacyBudgetBrowserTestForWorkersClientAdded,
+                       WorkersRecordWorkerClientAddedMetrics) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  content::DOMMessageQueue messages(web_contents());
+  base::RunLoop run_loop;
+
+  std::vector<uint64_t> expected_keys = {
+      blink::IdentifiableSurface::FromTypeAndToken(
+          blink::IdentifiableSurface::Type::kReservedInternal,
+          blink::IdentifiableSurface::ReservedSurfaceMetrics::
+              kWorkerClientAdded_ClientSourceId)
+          .ToUkmMetricHash(),
+      blink::IdentifiableSurface::FromTypeAndToken(
+          blink::IdentifiableSurface::Type::kReservedInternal,
+          blink::IdentifiableSurface::ReservedSurfaceMetrics::
+              kWorkerClientAdded_WorkerType)
+          .ToUkmMetricHash(),
+  };
+
+  // We wait for the expected metrics to be reported. Since some of the
+  // metrics are reported from the renderer process, this is the only reliable
+  // way to be sure we waited long enough.
+  auto quit_run_loop = [this, &expected_keys, &run_loop]() {
+    if (GetReportedSurfaceKeys(expected_keys).size() == expected_keys.size())
+      run_loop.Quit();
+  };
+
+  recorder().SetOnAddEntryCallback(ukm::builders::Identifiability::kEntryName,
+                                   base::BindLambdaForTesting(quit_run_loop));
+
+  ASSERT_TRUE(content::NavigateToURL(
+      web_contents(), embedded_test_server()->GetURL(FilePathXYZ() + ".html")));
+
+  // The document calls a bunch of instrumented functions and sends a message
+  // back to the test. Receipt of the message indicates that the script
+  // successfully completed.
+  std::string done;
+  ASSERT_TRUE(messages.WaitForMessage(&done));
+
+  // Wait for the metrics to come down the pipe.
+  run_loop.Run();
+
+  // The previously registered callback will be invalid after the test class is
+  // destructed.
+  recorder().SetOnAddEntryCallback(ukm::builders::Identifiability::kEntryName,
+                                   {});
+
+  // Test succeeds if there is no timeout. However, let's recheck the metrics
+  // here, so that if there is a timeout we get an output of which metrics are
+  // missing.
+  EXPECT_THAT(GetReportedSurfaceKeys(expected_keys),
+              UnorderedElementsAreArray(expected_keys));
+}
+
+IN_PROC_BROWSER_TEST_P(PrivacyBudgetBrowserTestForWorkersClientAdded,
+                       ReportWorkerClientAddedMetricForEveryRegisteredClient) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  content::DOMMessageQueue messages(web_contents());
+  base::RunLoop run_loop;
+
+  uint64_t expected_key =
+      blink::IdentifiableSurface::FromTypeAndToken(
+          blink::IdentifiableSurface::Type::kReservedInternal,
+          blink::IdentifiableSurface::ReservedSurfaceMetrics::
+              kWorkerClientAdded_ClientSourceId)
+          .ToUkmMetricHash();
+
+  // We wait for the expected metrics to be reported. Since some of the
+  // metrics are reported from the renderer process, this is the only reliable
+  // way to be sure we waited long enough.
+  auto quit_run_loop = [this, &expected_key, &run_loop]() {
+    if (GetSurfaceKeyCount(expected_key) == 2)
+      run_loop.Quit();
+  };
+
+  recorder().SetOnAddEntryCallback(ukm::builders::Identifiability::kEntryName,
+                                   base::BindLambdaForTesting(quit_run_loop));
+
+  ASSERT_TRUE(content::NavigateToURL(
+      web_contents(), embedded_test_server()->GetURL(
+                          FilePathXYZ() + "_with_two_clients.html")));
+
+  // The document calls a bunch of instrumented functions and sends a message
+  // back to the test. Receipt of the message indicates that the script
+  // successfully completed.
+  std::string done;
+  ASSERT_TRUE(messages.WaitForMessage(&done));
+
+  // Wait for the metrics to come down the pipe.
+  run_loop.Run();
+
+  // The previously registered callback will be invalid after the test class is
+  // destructed.
+  recorder().SetOnAddEntryCallback(ukm::builders::Identifiability::kEntryName,
+                                   {});
+
+  // Test succeeds if there is no timeout.
+  // Both surfaces should come from the same source but have different client
+  // ids.
+  std::vector<const ukm::mojom::UkmEntry*> entries =
+      recorder().GetEntriesByName(ukm::builders::Identifiability::kEntryName);
+
+  base::flat_set<uint64_t> source_ids;
+  base::flat_set<uint64_t> client_source_ids;
+  for (const auto* entry : entries) {
+    for (const auto& metric : entry->metrics) {
+      if (metric.first == expected_key) {
+        source_ids.insert(entry->source_id);
+        client_source_ids.insert(metric.second);
+      }
+    }
+  }
+  EXPECT_EQ(source_ids.size(), 1u);
+  EXPECT_EQ(client_source_ids.size(), 2u);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    PrivacyBudgetBrowserTestForWorkersClientAddedParameterized,
+    PrivacyBudgetBrowserTestForWorkersClientAdded,
+    ::testing::Values(
+// Shared workers are not supported on Android.
+#if !BUILDFLAG(IS_ANDROID)
+        "/privacy_budget/calls_shared_worker",
+#endif
+        "/privacy_budget/calls_service_worker"));
+
 IN_PROC_BROWSER_TEST_F(PrivacyBudgetBrowserTestWithTestRecorder,
                        EveryNavigationRecordsDocumentCreatedMetrics) {
   ASSERT_TRUE(embedded_test_server()->Start());
diff --git a/chrome/browser/privacy_budget/privacy_budget_browsertest_util.cc b/chrome/browser/privacy_budget/privacy_budget_browsertest_util.cc
index 505c820d..045e7bc 100644
--- a/chrome/browser/privacy_budget/privacy_budget_browsertest_util.cc
+++ b/chrome/browser/privacy_budget/privacy_budget_browsertest_util.cc
@@ -43,11 +43,31 @@
   return reported_surface_keys;
 }
 
+int PrivacyBudgetBrowserTestBaseWithTestRecorder::GetSurfaceKeyCount(
+    uint64_t expected_key) {
+  std::vector<const ukm::mojom::UkmEntry*> entries =
+      ukm_recorder_->GetEntriesByName(
+          ukm::builders::Identifiability::kEntryName);
+
+  int count = 0;
+  for (const auto* entry : entries) {
+    for (const auto& metric : entry->metrics) {
+      if (expected_key == metric.first)
+        count++;
+    }
+  }
+  return count;
+}
+
 content::WebContents*
 PrivacyBudgetBrowserTestBaseWithTestRecorder::web_contents() {
   return chrome_test_utils::GetActiveWebContents(this);
 }
 
+const std::string& PrivacyBudgetBrowserTestBaseWithTestRecorder::FilePathXYZ() {
+  return GetParam();
+}
+
 PrivacyBudgetBrowserTestBaseWithUkmRecording::
     PrivacyBudgetBrowserTestBaseWithUkmRecording()
     : SyncTest(SINGLE_CLIENT) {}
diff --git a/chrome/browser/privacy_budget/privacy_budget_browsertest_util.h b/chrome/browser/privacy_budget/privacy_budget_browsertest_util.h
index 9ca8bfd..8ba21b7 100644
--- a/chrome/browser/privacy_budget/privacy_budget_browsertest_util.h
+++ b/chrome/browser/privacy_budget/privacy_budget_browsertest_util.h
@@ -43,10 +43,15 @@
   base::flat_set<uint64_t> GetReportedSurfaceKeys(
       std::vector<uint64_t> expected_keys);
 
+  // Returns how many times a surface key was reported.
+  int GetSurfaceKeyCount(uint64_t expected_key);
+
   ukm::TestUkmRecorder& recorder() { return *ukm_recorder_; }
 
   content::WebContents* web_contents();
 
+  const std::string& FilePathXYZ();
+
  private:
   std::unique_ptr<ukm::TestAutoSetUkmRecorder> ukm_recorder_;
 };
diff --git a/chrome/browser/resources/chromeos/multidevice_internals/types.js b/chrome/browser/resources/chromeos/multidevice_internals/types.js
index 4d038f9..cb4a1bc 100644
--- a/chrome/browser/resources/chromeos/multidevice_internals/types.js
+++ b/chrome/browser/resources/chromeos/multidevice_internals/types.js
@@ -16,7 +16,7 @@
 
 /**
  * The type of log message object. The definition is based on
- * chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_logs_handler.cc:
+ * chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_logs_handler.cc:
  * LogMessageToDictionary()
  * @typedef {{text: string,
  *            time: string,
diff --git a/chrome/browser/resources/settings/chromeos/os_privacy_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_privacy_page/BUILD.gn
index a74b8d8..14c61e6 100644
--- a/chrome/browser/resources/settings/chromeos/os_privacy_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/os_privacy_page/BUILD.gn
@@ -66,6 +66,9 @@
     "//ui/webui/resources/js:cr.m",
     "//ui/webui/resources/js:load_time_data.m",
   ]
+
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_slider/cr_slider_externs.js" ]
 }
 
 js_library("privacy_hub_page") {
diff --git a/chrome/browser/resources/settings/chromeos/os_privacy_page/smart_privacy_page.html b/chrome/browser/resources/settings/chromeos/os_privacy_page/smart_privacy_page.html
index 057bb54..61b11dd7 100644
--- a/chrome/browser/resources/settings/chromeos/os_privacy_page/smart_privacy_page.html
+++ b/chrome/browser/resources/settings/chromeos/os_privacy_page/smart_privacy_page.html
@@ -8,6 +8,10 @@
     margin-inline-start: var(--cr-section-padding);
   }
 
+  .doubly-indented {
+    padding-inline-start: var(--cr-section-indent-padding);
+  }
+
   .underbar {
     border-bottom: var(--cr-separator-line);
   }
@@ -60,6 +64,24 @@
       sub-label="$i18n{smartPrivacyQuickDimSubtext}"
       deep-link-focus-id$="[[Setting.kQuickDim]]">
   </settings-toggle-button>
+  <iron-collapse id="quickDimOptions"
+      opened="[[prefs.power.quick_dim_enabled.value]]">
+    <div class="doubly-indented">
+      <div class="underbar indented"></div>
+      <div class="settings-box continuation">
+        <div class="start" aria-hidden="true">
+          $i18n{smartPrivacyQuickLockTitle}
+        </div>
+        <settings-slider
+          pref="{{prefs.power.quick_lock_delay.ms}}"
+          ticks="[[smartPrivacyQuickLockRangeMs_]]"
+          label-aria="$i18n{smartPrivacyQuickLockTitle}"
+          label-min="$i18n{smartPrivacyQuickLockShort}"
+          label-max="$i18n{smartPrivacyQuickLockLong}">
+        </settings-slider>
+      </div>
+    </div>
+  </iron-collapse>
 
   <!-- Underbar is only needed if we need to separate the two
        settings. -->
@@ -77,9 +99,13 @@
   </settings-toggle-button>
   <iron-collapse id="snoopingProtectionOptions"
       opened="[[prefs.ash.privacy.snooping_protection_enabled.value]]">
-      <settings-toggle-button class="settings-box continuation indented"
+    <div class="doubly-indented">
+      <div class="underbar indented"></div>
+      <settings-toggle-button
+          class="settings-box continuation"
           pref="{{prefs.ash.privacy.snooping_protection_notification_suppression_enabled}}"
           label="$i18n{smartPrivacySnoopingNotifications}">
       </settings-toggle-button>
+    </div>
   </iron-collapse>
 </template>
diff --git a/chrome/browser/resources/settings/chromeos/os_privacy_page/smart_privacy_page.js b/chrome/browser/resources/settings/chromeos/os_privacy_page/smart_privacy_page.js
index e6fa3163..8720aae 100644
--- a/chrome/browser/resources/settings/chromeos/os_privacy_page/smart_privacy_page.js
+++ b/chrome/browser/resources/settings/chromeos/os_privacy_page/smart_privacy_page.js
@@ -27,6 +27,26 @@
 import {RouteObserverBehavior, RouteObserverBehaviorInterface} from '../route_observer_behavior.js';
 
 /**
+ * The values that the quick lock slider can have, in ms.
+ * @const {!Array<number>}
+ */
+const QUICK_LOCK_DELAY_MS = [
+  30000,
+  60000,
+  120000,
+  180000,
+];
+
+/**
+ * Formatter for displaying duration text for the slider of quick dim
+ * delay.
+ * @const {Object}
+ */
+const secondsFormatter = new Intl.NumberFormat(
+    window.navigator.language,
+    {style: 'unit', unit: 'second', unitDisplay: 'narrow'});
+
+/**
  * @constructor
  * @extends {PolymerElement}
  * @implements {DeepLinkingBehaviorInterface}
@@ -78,6 +98,19 @@
       },
 
       /**
+       * Text that shows when moving the quick dim delay slider.
+       * @private {!Array<!SliderTick>}
+       */
+      smartPrivacyQuickLockRangeMs_: {
+        readOnly: true,
+        type: Array,
+        value() {
+          return QUICK_LOCK_DELAY_MS.map(
+              x => ({label: secondsFormatter.format(x / 1000), value: x}));
+        },
+      },
+
+      /**
        * Whether or not snooping protection is enabled.
        * @private {boolean}
        */
diff --git a/chrome/browser/resources/settings/site_settings/all_sites.html b/chrome/browser/resources/settings/site_settings/all_sites.html
index 66162f69..c749618 100644
--- a/chrome/browser/resources/settings/site_settings/all_sites.html
+++ b/chrome/browser/resources/settings/site_settings/all_sites.html
@@ -66,9 +66,11 @@
     </div>
     <div id="fpsLearnMore"
         hidden$="[[!shouldShowFpsLearnMore_(filter, filteredList_)]]">
-      <localized-link localized-string="[[getFpsLearnMoreLabel_(filter)]]"
-          link-url="$i18n{cookiesSettingsHelpCenterURL}">
-      </localized-link>
+      [[getFpsLearnMoreLabel_(filter)]]
+      <a href="$i18n{cookiesSettingsHelpCenterURL}"
+          aria-label="$i18n{siteSettingsFirstPartySetsLearnMoreAccessibility}">
+        $i18n{learnMore}
+      </a>
     </div>
     <div class="list-frame" hidden$="[[!siteGroupMapEmpty_(siteGroupMap)]]">
       <div class="list-item secondary">$i18n{emptyAllSitesPage}</div>
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
index 5b87f443..3e4f9064 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -137,7 +137,6 @@
 using content::RenderFrameHost;
 using content::WebContents;
 using security_interstitials::BaseSafeBrowsingErrorUI;
-using FeatureAndParams = base::test::FeatureRefAndParams;
 
 namespace safe_browsing {
 
@@ -1934,15 +1933,17 @@
       const SafeBrowsingBlockingPageDelayedWarningBrowserTest&) = delete;
 
   void SetUp() override {
-    std::vector<FeatureAndParams> enabled_features{
-        FeatureAndParams(blink::features::kPortals, {}),
-        FeatureAndParams(blink::features::kPortalsCrossOrigin, {}),
+    std::vector<base::test::FeatureRefAndParams> enabled_features{
+        base::test::FeatureRefAndParams(blink::features::kPortals, {}),
+        base::test::FeatureRefAndParams(blink::features::kPortalsCrossOrigin,
+                                        {}),
     };
     if (warning_on_mouse_click_enabled()) {
-      enabled_features.push_back(
-          FeatureAndParams(kDelayedWarnings, {{"mouse", "true"}}));
+      enabled_features.push_back(base::test::FeatureRefAndParams(
+          kDelayedWarnings, {{"mouse", "true"}}));
     } else {
-      enabled_features.push_back(FeatureAndParams(kDelayedWarnings, {}));
+      enabled_features.push_back(
+          base::test::FeatureRefAndParams(kDelayedWarnings, {}));
     }
 
     std::vector<base::test::FeatureRef> disabled_features;
@@ -2054,7 +2055,7 @@
  protected:
   // Subclasses can override to enable/disable features in SetUp().
   virtual void GetAdditionalFeatures(
-      std::vector<FeatureAndParams>* enabled_features,
+      std::vector<base::test::FeatureRefAndParams>* enabled_features,
       std::vector<base::test::FeatureRef>* disabled_features) {}
 
   // Initiates a download and waits for it to be completed or cancelled.
diff --git a/chrome/browser/search_resumption/OWNERS b/chrome/browser/search_resumption/OWNERS
index 88c5461..0a1c69a 100644
--- a/chrome/browser/search_resumption/OWNERS
+++ b/chrome/browser/search_resumption/OWNERS
@@ -1,2 +1 @@
 hanxi@chromium.org
-spdonghao@chromium.org
diff --git a/chrome/browser/storage_access_api/OWNERS b/chrome/browser/storage_access_api/OWNERS
index 8109981..e6b5dd8 100644
--- a/chrome/browser/storage_access_api/OWNERS
+++ b/chrome/browser/storage_access_api/OWNERS
@@ -1,5 +1,5 @@
 per-file *permission_context*=file://components/permissions/PERMISSIONS_OWNERS
-engedy@chromium.org
-mkwst@chromium.org
-mreichhoff@chromium.org
 cfredric@chromium.org
+engedy@chromium.org
+johannhof@chromium.org
+mreichhoff@chromium.org
diff --git a/chrome/browser/supervised_user/supervised_user_service_unittest.cc b/chrome/browser/supervised_user/supervised_user_service_unittest.cc
index 85304d32..bf2ec237 100644
--- a/chrome/browser/supervised_user/supervised_user_service_unittest.cc
+++ b/chrome/browser/supervised_user/supervised_user_service_unittest.cc
@@ -146,8 +146,14 @@
   std::unique_ptr<TestingProfile> profile_;
 };
 
-// TODO(crbug.com/1364589): Failing consistently
-TEST_F(SupervisedUserServiceTest, DISABLED_DeprecatedFilterPolicy) {
+// TODO(crbug.com/1364589): Failing consistently on linux-chromeos-dbg
+// due to failed timezone conversion assertion.
+#if BUILDFLAG(IS_CHROMEOS)
+#define MAYBE_DeprecatedFilterPolicy DISABLED_DeprecatedFilterPolicy
+#else
+#define MAYBE_DeprecatedFilterPolicy DeprecatedFilterPolicy
+#endif
+TEST_F(SupervisedUserServiceTest, MAYBE_DeprecatedFilterPolicy) {
   PrefService* prefs = profile_->GetPrefs();
   EXPECT_EQ(prefs->GetInteger(prefs::kDefaultSupervisedUserFilteringBehavior),
             SupervisedUserURLFilter::ALLOW);
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index f335c3d..6e8c9e8 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -2669,6 +2669,18 @@
       "webui/ash/launcher_internals/launcher_internals_handler.h",
       "webui/ash/launcher_internals/launcher_internals_ui.cc",
       "webui/ash/launcher_internals/launcher_internals_ui.h",
+      "webui/ash/multidevice_internals/multidevice_internals_logs_handler.cc",
+      "webui/ash/multidevice_internals/multidevice_internals_logs_handler.h",
+      "webui/ash/multidevice_internals/multidevice_internals_phone_hub_handler.cc",
+      "webui/ash/multidevice_internals/multidevice_internals_phone_hub_handler.h",
+      "webui/ash/multidevice_internals/multidevice_internals_ui.cc",
+      "webui/ash/multidevice_internals/multidevice_internals_ui.h",
+      "webui/ash/multidevice_setup/multidevice_setup_dialog.cc",
+      "webui/ash/multidevice_setup/multidevice_setup_dialog.h",
+      "webui/ash/multidevice_setup/multidevice_setup_handler.cc",
+      "webui/ash/multidevice_setup/multidevice_setup_handler.h",
+      "webui/ash/multidevice_setup/multidevice_setup_localized_strings_provider.cc",
+      "webui/ash/multidevice_setup/multidevice_setup_localized_strings_provider.h",
       "webui/chromeos/assistant_optin/assistant_optin_ui.cc",
       "webui/chromeos/assistant_optin/assistant_optin_ui.h",
       "webui/chromeos/assistant_optin/assistant_optin_utils.cc",
@@ -2857,18 +2869,6 @@
       "webui/chromeos/manage_mirrorsync/manage_mirrorsync_page_handler.h",
       "webui/chromeos/manage_mirrorsync/manage_mirrorsync_ui.cc",
       "webui/chromeos/manage_mirrorsync/manage_mirrorsync_ui.h",
-      "webui/chromeos/multidevice_internals/multidevice_internals_logs_handler.cc",
-      "webui/chromeos/multidevice_internals/multidevice_internals_logs_handler.h",
-      "webui/chromeos/multidevice_internals/multidevice_internals_phone_hub_handler.cc",
-      "webui/chromeos/multidevice_internals/multidevice_internals_phone_hub_handler.h",
-      "webui/chromeos/multidevice_internals/multidevice_internals_ui.cc",
-      "webui/chromeos/multidevice_internals/multidevice_internals_ui.h",
-      "webui/chromeos/multidevice_setup/multidevice_setup_dialog.cc",
-      "webui/chromeos/multidevice_setup/multidevice_setup_dialog.h",
-      "webui/chromeos/multidevice_setup/multidevice_setup_handler.cc",
-      "webui/chromeos/multidevice_setup/multidevice_setup_handler.h",
-      "webui/chromeos/multidevice_setup/multidevice_setup_localized_strings_provider.cc",
-      "webui/chromeos/multidevice_setup/multidevice_setup_localized_strings_provider.h",
       "webui/chromeos/network_logs_message_handler.cc",
       "webui/chromeos/network_logs_message_handler.h",
       "webui/chromeos/network_ui.cc",
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ConstraintsChecker.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ConstraintsChecker.java
index 11382b94..e1e8544d 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ConstraintsChecker.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ConstraintsChecker.java
@@ -4,8 +4,6 @@
 
 package org.chromium.chrome.browser.toolbar;
 
-import android.os.Handler;
-
 import androidx.annotation.NonNull;
 
 import org.chromium.base.Callback;
@@ -21,19 +19,15 @@
     private final ViewResourceAdapter mViewResourceAdapter;
     @NonNull
     private final ObservableSupplier<Integer> mConstraintsSupplier;
-    @NonNull
-    private final Handler mHandler;
 
     /**
      * @param viewResourceAdapter The target to notify when a capture is needed.
      * @param constraintsSupplier The underlying supplier for the state of constraints.
-     * @param handler Handler to post deferred tasks to.
      */
     public ConstraintsChecker(@NonNull ViewResourceAdapter viewResourceAdapter,
-            @NonNull ObservableSupplier<Integer> constraintsSupplier, @NonNull Handler handler) {
+            @NonNull ObservableSupplier<Integer> constraintsSupplier) {
         mViewResourceAdapter = viewResourceAdapter;
         mConstraintsSupplier = constraintsSupplier;
-        mHandler = handler;
     }
 
     /**
@@ -59,7 +53,7 @@
     public void onResult(Integer result) {
         if (!areControlsLocked()) {
             mConstraintsSupplier.removeObserver(this);
-            mHandler.post(() -> mViewResourceAdapter.onResourceRequested());
+            mViewResourceAdapter.onResourceRequested();
         }
     }
 }
\ No newline at end of file
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ConstraintsCheckerTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ConstraintsCheckerTest.java
index ebaa559..673ecf8e 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ConstraintsCheckerTest.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ConstraintsCheckerTest.java
@@ -5,13 +5,9 @@
 package org.chromium.chrome.browser.toolbar;
 
 import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
-import android.os.Handler;
-
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -34,22 +30,13 @@
 
     @Mock
     private ViewResourceAdapter mViewResourceAdapter;
-    @Mock
-    private Handler mHandler;
 
     private ObservableSupplierImpl mConstraintsSupplier = new ObservableSupplierImpl();
 
     @Test
     public void testScheduleRequestResourceOnUnlock() {
-        doAnswer((invocation) -> {
-            Runnable runnable = (Runnable) invocation.getArguments()[0];
-            runnable.run();
-            return null;
-        })
-                .when(mHandler)
-                .post(any(Runnable.class));
         ConstraintsChecker constraintsChecker =
-                new ConstraintsChecker(mViewResourceAdapter, mConstraintsSupplier, mHandler);
+                new ConstraintsChecker(mViewResourceAdapter, mConstraintsSupplier);
         constraintsChecker.scheduleRequestResourceOnUnlock();
         mConstraintsSupplier.set(BrowserControlsState.SHOWN);
         verify(mViewResourceAdapter, times(0)).onResourceRequested();
@@ -64,7 +51,7 @@
     @Test
     public void testAreControlsLocked() {
         ConstraintsChecker constraintsChecker =
-                new ConstraintsChecker(mViewResourceAdapter, mConstraintsSupplier, mHandler);
+                new ConstraintsChecker(mViewResourceAdapter, mConstraintsSupplier);
         assertEquals(true, constraintsChecker.areControlsLocked());
 
         mConstraintsSupplier.set(BrowserControlsState.SHOWN);
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/bottom/ScrollingBottomViewResourceFrameLayout.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/bottom/ScrollingBottomViewResourceFrameLayout.java
index 32f1b93..9651936 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/bottom/ScrollingBottomViewResourceFrameLayout.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/bottom/ScrollingBottomViewResourceFrameLayout.java
@@ -8,8 +8,6 @@
 import android.graphics.Canvas;
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
-import android.os.Handler;
-import android.os.Looper;
 import android.util.AttributeSet;
 
 import androidx.annotation.NonNull;
@@ -122,7 +120,6 @@
      */
     public void setConstraintsSupplier(ObservableSupplier<Integer> constraintsSupplier) {
         assert mConstraintsChecker == null;
-        mConstraintsChecker = new ConstraintsChecker(
-                getResourceAdapter(), constraintsSupplier, new Handler(Looper.getMainLooper()));
+        mConstraintsChecker = new ConstraintsChecker(getResourceAdapter(), constraintsSupplier);
     }
 }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java
index 51308db..876408f 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java
@@ -11,8 +11,6 @@
 import android.graphics.Region;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
-import android.os.Handler;
-import android.os.Looper;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
 import android.view.View;
@@ -239,8 +237,7 @@
 
             assert mConstraintsObserver == null;
             if (constraintsSupplier != null) {
-                mConstraintsObserver = new ConstraintsChecker(
-                        this, constraintsSupplier, new Handler(Looper.getMainLooper()));
+                mConstraintsObserver = new ConstraintsChecker(this, constraintsSupplier);
             }
 
             assert mTabSupplier == null;
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainerTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainerTest.java
index c28a563..955cfc81 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainerTest.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainerTest.java
@@ -18,7 +18,6 @@
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 import org.robolectric.annotation.Config;
-import org.robolectric.shadows.ShadowLooper;
 
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.metrics.UmaRecorderHolder;
@@ -219,7 +218,6 @@
 
         // BOTH should cause a new onResourceRequested call.
         mConstraintsSupplier.set(BrowserControlsState.BOTH);
-        ShadowLooper.idleMainLooper();
         Assert.assertEquals(1, onResourceRequestedCount.get());
 
         // The constraints should no longer block isDirty/captures.
diff --git a/chrome/browser/ui/app_list/search/games/game_provider_unittest.cc b/chrome/browser/ui/app_list/search/games/game_provider_unittest.cc
index b840dc0..3b7710e 100644
--- a/chrome/browser/ui/app_list/search/games/game_provider_unittest.cc
+++ b/chrome/browser/ui/app_list/search/games/game_provider_unittest.cc
@@ -26,7 +26,6 @@
 namespace app_list {
 namespace {
 
-using ::base::test::ScopedFeatureList;
 using ::testing::ElementsAre;
 using ::testing::UnorderedElementsAre;
 
@@ -71,7 +70,7 @@
  public:
   GameProviderTest() {
     bool enabled_override = GetParam();
-    std::vector<ScopedFeatureList::FeatureAndParams> enabled_features = {
+    std::vector<base::test::FeatureRefAndParams> enabled_features = {
         {ash::features::kProductivityLauncher, {}},
         {search_features::kLauncherGameSearch,
          {{"enabled_override", enabled_override ? "true" : "false"}}}};
@@ -113,7 +112,7 @@
 
   GameProvider* provider() const { return provider_; }
 
-  ScopedFeatureList feature_list_;
+  base::test::ScopedFeatureList feature_list_;
   content::BrowserTaskEnvironment task_environment_;
   ::test::TestAppListControllerDelegate list_controller_;
   std::unique_ptr<TestSearchController> search_controller_;
diff --git a/chrome/browser/ui/ash/system_tray_client_impl.cc b/chrome/browser/ui/ash/system_tray_client_impl.cc
index 9d563b9..5369924 100644
--- a/chrome/browser/ui/ash/system_tray_client_impl.cc
+++ b/chrome/browser/ui/ash/system_tray_client_impl.cc
@@ -50,10 +50,10 @@
 #include "chrome/browser/ui/settings_window_manager_chromeos.h"
 #include "chrome/browser/ui/singleton_tabs.h"
 #include "chrome/browser/ui/webui/access_code_cast/access_code_cast_dialog.h"
+#include "chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_dialog.h"
 #include "chrome/browser/ui/webui/chromeos/bluetooth_pairing_dialog.h"
 #include "chrome/browser/ui/webui/chromeos/internet_config_dialog.h"
 #include "chrome/browser/ui/webui/chromeos/internet_detail_dialog.h"
-#include "chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.h"
 #include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h"
 #include "chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom.h"
 #include "chrome/browser/upgrade_detector/upgrade_detector.h"
@@ -693,7 +693,7 @@
 }
 
 void SystemTrayClientImpl::ShowMultiDeviceSetup() {
-  chromeos::multidevice_setup::MultiDeviceSetupDialog::Show();
+  ash::multidevice_setup::MultiDeviceSetupDialog::Show();
 }
 
 void SystemTrayClientImpl::ShowFirmwareUpdate() {
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc b/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc
index 140aaed4..175787d 100644
--- a/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc
+++ b/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc
@@ -535,7 +535,7 @@
   syncer::SyncUserSettings* user_settings = sync_service->GetUserSettings();
   return user_settings->IsSyncAllOsTypesEnabled() ||
          profile->GetPrefs()->GetBoolean(
-             chromeos::settings::prefs::kSyncOsWallpaper);
+             ash::settings::prefs::kSyncOsWallpaper);
 }
 
 void WallpaperControllerClientImpl::OnVolumeMounted(
diff --git a/chrome/browser/ui/profile_picker.h b/chrome/browser/ui/profile_picker.h
index 86cb342..c419109 100644
--- a/chrome/browser/ui/profile_picker.h
+++ b/chrome/browser/ui/profile_picker.h
@@ -17,7 +17,6 @@
 #include "third_party/skia/include/core/SkColor.h"
 #include "url/gurl.h"
 
-class Browser;
 class GURL;
 class Profile;
 namespace content {
@@ -31,7 +30,6 @@
 
 class ProfilePicker {
  public:
-  using BrowserOpenedCallback = base::OnceCallback<void(Browser*)>;
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
   enum class FirstRunExitStatus {
     // The user completed the FRE and is continuing to launch the browser.
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc
index 4bf75837..6a7d2cca 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc
@@ -69,7 +69,6 @@
 #include "chrome/browser/ash/input_method/mock_input_method_manager_impl.h"
 #endif
 
-using FeatureAndParams = base::test::FeatureRefAndParams;
 using gfx::Range;
 using metrics::OmniboxEventProto;
 
@@ -299,7 +298,7 @@
 class OmniboxViewViewsTestBase : public ChromeViewsTestBase {
  public:
   OmniboxViewViewsTestBase(
-      const std::vector<FeatureAndParams>& enabled_features,
+      const std::vector<base::test::FeatureRefAndParams>& enabled_features,
       const std::vector<base::test::FeatureRef>& disabled_features,
       bool is_rtl_ui_test = false) {
     scoped_feature_list_.InitWithFeaturesAndParameters(enabled_features,
@@ -314,12 +313,12 @@
 class OmniboxViewViewsTest : public OmniboxViewViewsTestBase {
  public:
   OmniboxViewViewsTest(
-      const std::vector<FeatureAndParams>& enabled_features,
+      const std::vector<base::test::FeatureRefAndParams>& enabled_features,
       const std::vector<base::test::FeatureRef>& disabled_features,
       bool is_rtl_ui_test = false);
 
   OmniboxViewViewsTest()
-      : OmniboxViewViewsTest(std::vector<FeatureAndParams>(),
+      : OmniboxViewViewsTest(std::vector<base::test::FeatureRefAndParams>(),
                              std::vector<base::test::FeatureRef>()) {}
   OmniboxViewViewsTest(const OmniboxViewViewsTest&) = delete;
   OmniboxViewViewsTest& operator=(const OmniboxViewViewsTest&) = delete;
@@ -396,7 +395,7 @@
 };
 
 OmniboxViewViewsTest::OmniboxViewViewsTest(
-    const std::vector<FeatureAndParams>& enabled_features,
+    const std::vector<base::test::FeatureRefAndParams>& enabled_features,
     const std::vector<base::test::FeatureRef>& disabled_features,
     bool is_rtl_ui_test)
     : OmniboxViewViewsTestBase(enabled_features,
diff --git a/chrome/browser/ui/views/performance_controls/battery_saver_button_browsertest.cc b/chrome/browser/ui/views/performance_controls/battery_saver_button_browsertest.cc
index 29579236..1660d5a 100644
--- a/chrome/browser/ui/views/performance_controls/battery_saver_button_browsertest.cc
+++ b/chrome/browser/ui/views/performance_controls/battery_saver_button_browsertest.cc
@@ -51,9 +51,12 @@
   ~BatterySaverHelpPromoTest() override = default;
 
   void SetUp() override {
-    feature_list_.InitWithFeatures(
-        {feature_engagement::kIPHBatterySaverModeFeature,
-         performance_manager::features::kBatterySaverModeAvailable},
+    feature_list_.InitWithFeaturesAndParameters(
+        {{feature_engagement::kIPHDemoMode,
+          {{feature_engagement::kIPHDemoModeFeatureChoiceParam,
+            feature_engagement::kIPHBatterySaverModeFeature.name}}},
+         {feature_engagement::kIPHBatterySaverModeFeature, {}},
+         {performance_manager::features::kBatterySaverModeAvailable, {}}},
         {});
 
     SetUpFakeBatterySampler();
diff --git a/chrome/browser/ui/views/profiles/first_run_flow_controller_lacros.cc b/chrome/browser/ui/views/profiles/first_run_flow_controller_lacros.cc
index 45ef7ce..0545512 100644
--- a/chrome/browser/ui/views/profiles/first_run_flow_controller_lacros.cc
+++ b/chrome/browser/ui/views/profiles/first_run_flow_controller_lacros.cc
@@ -14,10 +14,10 @@
 namespace {
 
 // Helper to run `callback`, after hiding the profile picker.
-void HideProfilePickerAndRun(ProfilePicker::BrowserOpenedCallback callback) {
+void HideProfilePickerAndRun(PostHostClearedCallback callback) {
   ProfilePicker::Hide();
 
-  if (!callback)
+  if (callback->is_null())
     return;
 
   // See if there is already a browser we can use.
@@ -35,7 +35,7 @@
     return;
   }
 
-  std::move(callback).Run(browser);
+  std::move(callback.value()).Run(browser);
 }
 
 }  // namespace
@@ -48,16 +48,16 @@
       first_run_exited_callback_(std::move(first_run_exited_callback)) {
   DCHECK(first_run_exited_callback_);
 
-  auto finish_and_continue_in_browser_callback =
+  auto finish_flow_callback = FinishFlowCallback(
       base::BindOnce(&FirstRunFlowControllerLacros::ExitFlowAndRun,
                      // Unretained ok: the callback is passed to a step that
                      // the `this` will own and outlive.
-                     base::Unretained(this));
+                     base::Unretained(this)));
 
   auto signed_in_flow = std::make_unique<LacrosFirstRunSignedInFlowController>(
       host, profile,
       content::WebContents::Create(content::WebContents::CreateParams(profile)),
-      std::move(finish_and_continue_in_browser_callback));
+      std::move(finish_flow_callback));
   signed_in_flow_ = signed_in_flow->GetWeakPtr();
 
   RegisterStep(initial_step(),
@@ -66,9 +66,8 @@
 }
 
 FirstRunFlowControllerLacros::~FirstRunFlowControllerLacros() {
-  // Call the callback if not called yet. This can happen in case of early
-  // exits for example, the original intent callback just gets dropped. See
-  // https://crbug.com/1307754.
+  // Call the callback if not called yet. This happens when the user exits the
+  // flow by closing the window, or for intent overrides.
   if (first_run_exited_callback_ && signed_in_flow_) {
     std::move(first_run_exited_callback_)
         .Run(signed_in_flow_->sync_confirmation_seen()
@@ -83,12 +82,7 @@
 }
 
 void FirstRunFlowControllerLacros::ExitFlowAndRun(
-    ProfilePicker::BrowserOpenedCallback callback) {
-  ProfileManager* profile_manager = g_browser_process->profile_manager();
-  Profile* profile = profile_manager->GetProfileByPath(
-      profile_manager->GetPrimaryUserProfilePath());
-  DCHECK(profile);
-
+    PostHostClearedCallback callback) {
   std::move(first_run_exited_callback_)
       .Run(ProfilePicker::FirstRunExitStatus::kCompleted,
            ProfilePicker::FirstRunExitSource::kFlowFinished,
diff --git a/chrome/browser/ui/views/profiles/first_run_flow_controller_lacros.h b/chrome/browser/ui/views/profiles/first_run_flow_controller_lacros.h
index be4a5a1..732bad5 100644
--- a/chrome/browser/ui/views/profiles/first_run_flow_controller_lacros.h
+++ b/chrome/browser/ui/views/profiles/first_run_flow_controller_lacros.h
@@ -8,11 +8,16 @@
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/ui/profile_picker.h"
 #include "chrome/browser/ui/views/profiles/profile_management_flow_controller.h"
+#include "chrome/browser/ui/views/profiles/profile_management_utils.h"
 
 class LacrosFirstRunSignedInFlowController;
 
 class FirstRunFlowControllerLacros : public ProfileManagementFlowController {
  public:
+  // Profile management flow controller that will run the FRE for `profile` in
+  // `host`.
+  // `first_run_exited_callback` is guaranteed to be called when the flow is
+  // exited.
   FirstRunFlowControllerLacros(
       ProfilePickerWebContentsHost* host,
       Profile* profile,
@@ -25,11 +30,11 @@
   ~FirstRunFlowControllerLacros() override;
 
  private:
-  void ExitFlowAndRun(ProfilePicker::BrowserOpenedCallback callback);
+  void ExitFlowAndRun(PostHostClearedCallback callback);
 
   // Captures the operation that the user expected to run at the time we chose
-  // to show them the FRE. When we complete the FRE, we run this and we expect
-  // that it will cause a browser to be opened.
+  // to show them the FRE. When we exit the FRE, we MUST run this. We expect
+  // that it will cause a UI for the primary profile to be opened.
   ProfilePicker::DebugFirstRunExitedCallback first_run_exited_callback_;
 
   // Gives access to the signed-in flow controller, which is owned by the step.
diff --git a/chrome/browser/ui/views/profiles/lacros_first_run_signed_in_flow_controller.cc b/chrome/browser/ui/views/profiles/lacros_first_run_signed_in_flow_controller.cc
index fe946c3..b2763ef 100644
--- a/chrome/browser/ui/views/profiles/lacros_first_run_signed_in_flow_controller.cc
+++ b/chrome/browser/ui/views/profiles/lacros_first_run_signed_in_flow_controller.cc
@@ -6,10 +6,8 @@
 
 #include "base/logging.h"
 #include "base/scoped_observation.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/views/profiles/profile_management_utils.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
 
 namespace {
@@ -47,13 +45,12 @@
     ProfilePickerWebContentsHost* host,
     Profile* profile,
     std::unique_ptr<content::WebContents> contents,
-    base::OnceCallback<void(ProfilePicker::BrowserOpenedCallback
-                                maybe_callback)> flow_completed_callback)
+    FinishFlowCallback finish_flow_callback)
     : ProfilePickerSignedInFlowController(host,
                                           profile,
                                           std::move(contents),
                                           absl::optional<SkColor>()),
-      flow_completed_callback_(std::move(flow_completed_callback)) {}
+      finish_flow_callback_(std::move(finish_flow_callback)) {}
 
 LacrosFirstRunSignedInFlowController::~LacrosFirstRunSignedInFlowController() =
     default;
@@ -90,9 +87,9 @@
 }
 
 void LacrosFirstRunSignedInFlowController::FinishAndOpenBrowser(
-    ProfilePicker::BrowserOpenedCallback callback) {
-  if (flow_completed_callback_)
-    std::move(flow_completed_callback_).Run(std::move(callback));
+    PostHostClearedCallback callback) {
+  if (finish_flow_callback_.value())
+    std::move(finish_flow_callback_.value()).Run(std::move(callback));
 }
 
 void LacrosFirstRunSignedInFlowController::SwitchToSyncConfirmation() {
diff --git a/chrome/browser/ui/views/profiles/lacros_first_run_signed_in_flow_controller.h b/chrome/browser/ui/views/profiles/lacros_first_run_signed_in_flow_controller.h
index 86f5594..0efdf6b0 100644
--- a/chrome/browser/ui/views/profiles/lacros_first_run_signed_in_flow_controller.h
+++ b/chrome/browser/ui/views/profiles/lacros_first_run_signed_in_flow_controller.h
@@ -6,21 +6,21 @@
 #define CHROME_BROWSER_UI_VIEWS_PROFILES_LACROS_FIRST_RUN_SIGNED_IN_FLOW_CONTROLLER_H_
 
 #include "base/memory/weak_ptr.h"
+#include "chrome/browser/ui/views/profiles/profile_management_utils.h"
 #include "chrome/browser/ui/views/profiles/profile_picker_signed_in_flow_controller.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
 
 class LacrosFirstRunSignedInFlowController
     : public ProfilePickerSignedInFlowController {
  public:
-  // `flow_completed_callback` gets called when the user completes the FRE.
-  // It gets `maybe_callback` as a parameter which is empty in most cases but
-  // must be called on a newly opened browser window if non-empty.
+  // `finish_flow_callback` will be called when the user completes the FRE, but
+  // might not be executed, for example if this object is destroyed before the
+  // flow is completed.
   LacrosFirstRunSignedInFlowController(
       ProfilePickerWebContentsHost* host,
       Profile* profile,
       std::unique_ptr<content::WebContents> contents,
-      base::OnceCallback<void(ProfilePicker::BrowserOpenedCallback
-                                  maybe_callback)> flow_completed_callback);
+      FinishFlowCallback finish_flow_callback);
   ~LacrosFirstRunSignedInFlowController() override;
 
   bool sync_confirmation_seen() const { return sync_confirmation_seen_; }
@@ -31,8 +31,7 @@
 
   // ProfilePickerSignedInFlowController:
   void Init() override;
-  void FinishAndOpenBrowser(
-      ProfilePicker::BrowserOpenedCallback callback) override;
+  void FinishAndOpenBrowser(PostHostClearedCallback callback) override;
   void SwitchToSyncConfirmation() override;
 
  protected:
@@ -42,9 +41,9 @@
   // Tracks whether the user got to the last step of the FRE flow.
   bool sync_confirmation_seen_ = false;
 
-  // Callback that gets called if the first run flow is completed.
-  base::OnceCallback<void(ProfilePicker::BrowserOpenedCallback maybe_callback)>
-      flow_completed_callback_;
+  // Callback that will be called when the user completes all the steps in the
+  // flow, to finalize and close it.
+  FinishFlowCallback finish_flow_callback_;
 
   std::unique_ptr<signin::IdentityManager::Observer> can_retry_init_observer_;
 
diff --git a/chrome/browser/ui/views/profiles/profile_creation_signed_in_flow_controller.cc b/chrome/browser/ui/views/profiles/profile_creation_signed_in_flow_controller.cc
index 20dbc89..1925ac3 100644
--- a/chrome/browser/ui/views/profiles/profile_creation_signed_in_flow_controller.cc
+++ b/chrome/browser/ui/views/profiles/profile_creation_signed_in_flow_controller.cc
@@ -131,7 +131,7 @@
 }
 
 void ProfileCreationSignedInFlowController::FinishAndOpenBrowser(
-    ProfilePicker::BrowserOpenedCallback callback) {
+    PostHostClearedCallback callback) {
   // Do nothing if the sign-in flow is aborted or if this has already been
   // called. Note that this can get called first time from a special case
   // handling (such as the Settings link) and than second time when the
@@ -153,7 +153,7 @@
 }
 
 void ProfileCreationSignedInFlowController::FinishAndOpenBrowserImpl(
-    ProfilePicker::BrowserOpenedCallback callback) {
+    PostHostClearedCallback callback) {
   TRACE_EVENT1(
       "browser",
       "ProfileCreationSignedInFlowController::FinishAndOpenBrowserImpl",
@@ -170,14 +170,16 @@
 
   // If there's no custom callback specified (that overrides profile
   // customization bubble), Chrome should show the customization bubble.
-  if (!callback) {
+  if (callback->is_null()) {
     // If there's no color to apply to the profile, skip the customization
     // bubble and trigger an IPH, instead.
     if (ThemeServiceFactory::GetForProfile(profile())->UsingPolicyTheme() ||
         !GetProfileColor().has_value()) {
-      callback = base::BindOnce(&MaybeShowProfileSwitchIPH);
+      callback =
+          PostHostClearedCallback(base::BindOnce(&MaybeShowProfileSwitchIPH));
     } else {
-      callback = base::BindOnce(&ShowCustomizationBubble, GetProfileColor());
+      callback = PostHostClearedCallback(
+          base::BindOnce(&ShowCustomizationBubble, GetProfileColor()));
 
       // If sync cannot start, we apply `GetProfileColor()` right away before
       // opening a browser window to avoid flicker. Otherwise, it's applied
@@ -195,7 +197,7 @@
 }
 
 void ProfileCreationSignedInFlowController::ExitPickerAndRunInNewBrowser(
-    ProfilePicker::BrowserOpenedCallback callback) {
+    PostHostClearedCallback callback) {
   profiles::OpenBrowserWindowForProfile(
       base::BindOnce(&ProfileCreationSignedInFlowController::OnBrowserOpened,
                      weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
@@ -232,12 +234,12 @@
   ProfileMetrics::LogProfileAddNewUser(
       ProfileMetrics::ADD_NEW_PROFILE_PICKER_SIGNED_IN);
 
-  ExitPickerAndRunInNewBrowser(
-      base::BindOnce(&ContinueSAMLSignin, ReleaseContents()));
+  ExitPickerAndRunInNewBrowser(PostHostClearedCallback(
+      base::BindOnce(&ContinueSAMLSignin, ReleaseContents())));
 }
 
 void ProfileCreationSignedInFlowController::OnBrowserOpened(
-    ProfilePicker::BrowserOpenedCallback finish_flow_callback,
+    PostHostClearedCallback finish_flow_callback,
     Profile* profile_with_browser_opened) {
   CHECK_EQ(profile_with_browser_opened, profile());
   TRACE_EVENT1("browser",
@@ -248,10 +250,10 @@
   // window incl. this view.
   host()->Clear();
 
-  if (!finish_flow_callback)
+  if (finish_flow_callback->is_null())
     return;
 
   Browser* browser = chrome::FindLastActiveWithProfile(profile());
   CHECK(browser);
-  std::move(finish_flow_callback).Run(browser);
+  std::move(finish_flow_callback.value()).Run(browser);
 }
diff --git a/chrome/browser/ui/views/profiles/profile_creation_signed_in_flow_controller.h b/chrome/browser/ui/views/profiles/profile_creation_signed_in_flow_controller.h
index cb4bdd40..7ae6e4eb 100644
--- a/chrome/browser/ui/views/profiles/profile_creation_signed_in_flow_controller.h
+++ b/chrome/browser/ui/views/profiles/profile_creation_signed_in_flow_controller.h
@@ -31,13 +31,14 @@
   // ProfilePickerSignedInFlowController:
   void Init() override;
   void Cancel() override;
-  void FinishAndOpenBrowser(
-      ProfilePicker::BrowserOpenedCallback callback) override;
+  // If empty `callback` is provided, the default action is performed: showing
+  // the profile customization bubble and/or profile IPH.
+  void FinishAndOpenBrowser(PostHostClearedCallback callback) override;
 
  private:
   // Finishes the non-SAML flow, registering customisation-related callbacks if
   // no `callback` is povided.
-  void FinishAndOpenBrowserImpl(ProfilePicker::BrowserOpenedCallback callback);
+  void FinishAndOpenBrowserImpl(PostHostClearedCallback callback);
 
   // Finishes the SAML flow by continuing the sign-in in a browser window.
   void FinishAndOpenBrowserForSAML();
@@ -45,14 +46,12 @@
 
   // Shared helper. Opens a new browser window, closes the picker and runs
   // `callback` in the opened window.
-  void ExitPickerAndRunInNewBrowser(
-      ProfilePicker::BrowserOpenedCallback callback);
+  void ExitPickerAndRunInNewBrowser(PostHostClearedCallback callback);
 
   // Internal callback to finish the last steps of the signed-in creation
   // flow.
-  void OnBrowserOpened(
-      ProfilePicker::BrowserOpenedCallback finish_flow_callback,
-      Profile* profile_with_browser_opened);
+  void OnBrowserOpened(PostHostClearedCallback finish_flow_callback,
+                       Profile* profile_with_browser_opened);
 
   // Stores whether this is profile creation for saml sign-in (that skips most
   // of the logic).
diff --git a/chrome/browser/ui/views/profiles/profile_management_utils.h b/chrome/browser/ui/views/profiles/profile_management_utils.h
index e4908b1b..ba0fd4a 100644
--- a/chrome/browser/ui/views/profiles/profile_management_utils.h
+++ b/chrome/browser/ui/views/profiles/profile_management_utils.h
@@ -8,10 +8,29 @@
 #include <string>
 
 #include "base/cancelable_callback.h"
+#include "base/types/strong_alias.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
 
+class Browser;
 class Profile;
 
+// Callback executed when the flow finishes, after the host was cleared and
+// we opened a browser for the newly set up profile.
+// This callback should not rely on profile management flow instances, as we
+// assume that they are deleted when the host is cleared.
+// The provided `Browser*` should not be `nullptr`. (This assumption is expected
+// to change in the future, see crbug.com/1374315.)
+using PostHostClearedCallback =
+    base::StrongAlias<class PostHostClearedCallbackTag,
+                      base::OnceCallback<void(Browser*)>>;
+
+// Callback to run to finish the flow. If a `PostHostClearedCallback` is
+// provided, it will be executed after the host is cleared, and will be given
+// a browser window for the newly set up profile.
+using FinishFlowCallback =
+    base::StrongAlias<class FinishFlowCallbackTag,
+                      base::OnceCallback<void(PostHostClearedCallback)>>;
+
 // Updates prefs and entries for `profile` to make it ready to be used
 // normally by the user.
 void FinalizeNewProfileSetup(Profile* profile,
diff --git a/chrome/browser/ui/views/profiles/profile_picker_signed_in_flow_controller.cc b/chrome/browser/ui/views/profiles/profile_picker_signed_in_flow_controller.cc
index 4529bfcd..3fd16d6 100644
--- a/chrome/browser/ui/views/profiles/profile_picker_signed_in_flow_controller.cc
+++ b/chrome/browser/ui/views/profiles/profile_picker_signed_in_flow_controller.cc
@@ -9,6 +9,7 @@
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/themes/theme_service.h"
 #include "chrome/browser/themes/theme_service_factory.h"
+#include "chrome/browser/ui/views/profiles/profile_management_utils.h"
 #include "chrome/browser/ui/views/profiles/profile_picker_turn_sync_on_delegate.h"
 #include "chrome/browser/ui/webui/signin/signin_url_utils.h"
 #include "chrome/browser/ui/webui/signin/sync_confirmation_ui.h"
@@ -54,9 +55,9 @@
                                      "primary account must be passed in.";
   email_ = account_info.email;
 
-  base::OnceClosure sync_consent_completed_closure = base::BindOnce(
-      &ProfilePickerSignedInFlowController::FinishAndOpenBrowser,
-      weak_ptr_factory_.GetWeakPtr(), ProfilePicker::BrowserOpenedCallback());
+  base::OnceClosure sync_consent_completed_closure =
+      base::BindOnce(&ProfilePickerSignedInFlowController::FinishAndOpenBrowser,
+                     weak_ptr_factory_.GetWeakPtr(), PostHostClearedCallback());
 
   // TurnSyncOnHelper deletes itself once done.
   new TurnSyncOnHelper(
diff --git a/chrome/browser/ui/views/profiles/profile_picker_signed_in_flow_controller.h b/chrome/browser/ui/views/profiles/profile_picker_signed_in_flow_controller.h
index 6612a643..b62a7de 100644
--- a/chrome/browser/ui/views/profiles/profile_picker_signed_in_flow_controller.h
+++ b/chrome/browser/ui/views/profiles/profile_picker_signed_in_flow_controller.h
@@ -5,12 +5,11 @@
 #ifndef CHROME_BROWSER_UI_VIEWS_PROFILES_PROFILE_PICKER_SIGNED_IN_FLOW_CONTROLLER_H_
 #define CHROME_BROWSER_UI_VIEWS_PROFILES_PROFILE_PICKER_SIGNED_IN_FLOW_CONTROLLER_H_
 
-#include "base/callback.h"
 #include "base/files/file_path.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/profiles/keep_alive/scoped_profile_keep_alive.h"
-#include "chrome/browser/ui/profile_picker.h"
+#include "chrome/browser/ui/views/profiles/profile_management_utils.h"
 #include "chrome/browser/ui/views/profiles/profile_picker_web_contents_host.h"
 #include "chrome/browser/ui/webui/signin/enterprise_profile_welcome_ui.h"
 #include "content/public/browser/web_contents_delegate.h"
@@ -49,12 +48,12 @@
   // was closed.
   virtual void Cancel();
 
-  // Finishes the creation flow by marking `profile_being_created_` as fully
-  // created, opening a browser window for this profile and calling
-  // `callback`. If empty `callback` is provided, the default action is
-  // performed: showing the profile customization bubble and/or profile IPH.
-  virtual void FinishAndOpenBrowser(
-      ProfilePicker::BrowserOpenedCallback callback) = 0;
+  // Finishes the creation flow for `profile_`: marks it fully created,
+  // transitions from `host_` to a new browser window and calls `callback` if
+  // the browser window was successfully opened.
+  // TODO(crbug.com/1374315): Tighten this contract by notifying the caller if
+  // the browser open was not possible.
+  virtual void FinishAndOpenBrowser(PostHostClearedCallback callback) = 0;
 
   // Finishes the sign-in process by moving to the sync confirmation screen.
   virtual void SwitchToSyncConfirmation();
diff --git a/chrome/browser/ui/views/profiles/profile_picker_turn_sync_on_delegate.cc b/chrome/browser/ui/views/profiles/profile_picker_turn_sync_on_delegate.cc
index 4907827..e336b31 100644
--- a/chrome/browser/ui/views/profiles/profile_picker_turn_sync_on_delegate.cc
+++ b/chrome/browser/ui/views/profiles/profile_picker_turn_sync_on_delegate.cc
@@ -8,12 +8,9 @@
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/policy/profile_policy_connector.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/browser/ui/profile_picker.h"
-#include "chrome/browser/ui/ui_features.h"
+#include "chrome/browser/ui/views/profiles/profile_management_utils.h"
 #include "chrome/browser/ui/webui/signin/login_ui_service.h"
 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
 #include "chrome/browser/ui/webui/signin/signin_ui_error.h"
@@ -86,7 +83,7 @@
   if (IsLacrosPrimaryProfileFirstRun(profile_)) {
     // The primary profile onboarding is silently skipped if there's any error.
     if (controller_)
-      controller_->FinishAndOpenBrowser(ProfilePicker::BrowserOpenedCallback());
+      controller_->FinishAndOpenBrowser(PostHostClearedCallback());
     return;
   }
 
@@ -103,8 +100,8 @@
 
   // Open the browser and when it's done, show the login error.
   if (controller_) {
-    controller_->FinishAndOpenBrowser(base::BindOnce(
-        &TurnSyncOnHelper::Delegate::ShowLoginErrorForBrowser, error));
+    controller_->FinishAndOpenBrowser(PostHostClearedCallback(base::BindOnce(
+        &TurnSyncOnHelper::Delegate::ShowLoginErrorForBrowser, error)));
   }
 }
 
@@ -198,7 +195,8 @@
 void ProfilePickerTurnSyncOnDelegate::ShowSyncSettings() {
   // Open the browser and when it's done, open settings in the browser.
   if (controller_) {
-    controller_->FinishAndOpenBrowser(base::BindOnce(&OpenSettingsInBrowser));
+    controller_->FinishAndOpenBrowser(
+        PostHostClearedCallback(base::BindOnce(&OpenSettingsInBrowser)));
   }
 }
 
diff --git a/chrome/browser/ui/views/web_apps/frame_toolbar/system_app_accessible_name.cc b/chrome/browser/ui/views/web_apps/frame_toolbar/system_app_accessible_name.cc
index e49d772..1523866 100644
--- a/chrome/browser/ui/views/web_apps/frame_toolbar/system_app_accessible_name.cc
+++ b/chrome/browser/ui/views/web_apps/frame_toolbar/system_app_accessible_name.cc
@@ -28,7 +28,7 @@
 
 void SystemAppAccessibleName::GetAccessibleNodeData(ui::AXNodeData* node_data) {
   node_data->role = ax::mojom::Role::kApplication;
-  node_data->SetName(app_name_);
+  node_data->SetNameChecked(app_name_);
 }
 
 BEGIN_METADATA(SystemAppAccessibleName, views::View)
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 2bda791..f0ae7e5 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
@@ -134,6 +134,16 @@
 #include "ash/constants/ash_features.h"
 #endif
 
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+#include "base/version.h"
+#include "chrome/browser/apps/app_service/app_service_proxy_lacros.h"
+#include "chromeos/crosapi/mojom/test_controller.mojom-test-utils.h"
+#include "chromeos/crosapi/mojom/test_controller.mojom.h"
+#include "chromeos/lacros/lacros_service.h"
+#include "chromeos/lacros/lacros_test_helper.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#endif
+
 #if BUILDFLAG(IS_MAC)
 #include <ImageIO/ImageIO.h>
 #include "chrome/browser/apps/app_shim/app_shim_manager_mac.h"
@@ -611,6 +621,28 @@
   views::test::AcceptDialog(widget);
 }
 
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+
+// Clear any apps that may have been left in the Ash App Service cache by
+// earlier tests.
+void ReinitializeAppService(Profile* profile) {
+  if (chromeos::IsAshVersionAtLeastForTesting(base::Version({108, 0, 5354}))) {
+    crosapi::mojom::TestControllerAsyncWaiter(
+        chromeos::LacrosService::Get()
+            ->GetRemote<crosapi::mojom::TestController>()
+            .get())
+        .ReinitializeAppService();
+
+    apps::AppServiceProxyFactory::GetForProfile(profile)
+        ->ReinitializeForTesting(profile);
+    AppTypeInitializationWaiter(profile, apps::AppType::kWeb).Await();
+  } else {
+    LOG(ERROR) << "Cannot ReinitializeAppService - Unsupported ash version.";
+  }
+}
+
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
 }  // anonymous namespace
 
 BrowserState::BrowserState(
@@ -771,6 +803,11 @@
   if (!delegate_->IsSyncTest()) {
     observation_.Observe(&provider()->install_manager());
   }
+
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  ReinitializeAppService(browser()->profile());
+#endif
+
   web_app::test::WaitUntilReady(
       web_app::WebAppProvider::GetForTest(browser()->profile()));
 }
diff --git a/chrome/browser/ui/web_applications/OWNERS b/chrome/browser/ui/web_applications/OWNERS
index 1255a2c..7b9d8eb 100644
--- a/chrome/browser/ui/web_applications/OWNERS
+++ b/chrome/browser/ui/web_applications/OWNERS
@@ -1 +1,3 @@
 file://chrome/browser/web_applications/OWNERS
+
+per-file sub_apps_service_impl*=isandrk@chromium.org
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_internals/DIR_METADATA b/chrome/browser/ui/webui/ash/multidevice_internals/DIR_METADATA
similarity index 100%
rename from chrome/browser/ui/webui/chromeos/multidevice_internals/DIR_METADATA
rename to chrome/browser/ui/webui/ash/multidevice_internals/DIR_METADATA
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_internals/OWNERS b/chrome/browser/ui/webui/ash/multidevice_internals/OWNERS
similarity index 100%
rename from chrome/browser/ui/webui/chromeos/multidevice_internals/OWNERS
rename to chrome/browser/ui/webui/ash/multidevice_internals/OWNERS
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_logs_handler.cc b/chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_logs_handler.cc
similarity index 92%
rename from chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_logs_handler.cc
rename to chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_logs_handler.cc
index bc4bf3b4..ecbdaaa6 100644
--- a/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_logs_handler.cc
+++ b/chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_logs_handler.cc
@@ -2,16 +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/webui/chromeos/multidevice_internals/multidevice_internals_logs_handler.h"
+#include "chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_logs_handler.h"
 
 #include "base/bind.h"
 #include "base/i18n/time_formatting.h"
 #include "base/values.h"
 #include "chromeos/ash/components/multidevice/logging/log_buffer.h"
 
-namespace chromeos {
-
-namespace multidevice {
+namespace ash::multidevice {
 
 namespace {
 
@@ -78,6 +76,4 @@
                     LogMessageToDictionary(log_message));
 }
 
-}  // namespace multidevice
-
-}  // namespace chromeos
+}  // namespace ash::multidevice
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_logs_handler.h b/chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_logs_handler.h
similarity index 77%
rename from chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_logs_handler.h
rename to chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_logs_handler.h
index a36e472..bd01038 100644
--- a/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_logs_handler.h
+++ b/chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_logs_handler.h
@@ -2,17 +2,15 @@
 // 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_CHROMEOS_MULTIDEVICE_INTERNALS_MULTIDEVICE_INTERNALS_LOGS_HANDLER_H_
-#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_MULTIDEVICE_INTERNALS_MULTIDEVICE_INTERNALS_LOGS_HANDLER_H_
+#ifndef CHROME_BROWSER_UI_WEBUI_ASH_MULTIDEVICE_INTERNALS_MULTIDEVICE_INTERNALS_LOGS_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_ASH_MULTIDEVICE_INTERNALS_MULTIDEVICE_INTERNALS_LOGS_HANDLER_H_
 
 #include "base/scoped_observation.h"
 #include "base/values.h"
 #include "chromeos/ash/components/multidevice/logging/log_buffer.h"
 #include "content/public/browser/web_ui_message_handler.h"
 
-namespace chromeos {
-
-namespace multidevice {
+namespace ash::multidevice {
 
 // WebUIMessageHandler for the PA_LOG Macro to pass logging messages to the
 // chrome://multidevice-internals logging tab.
@@ -43,8 +41,6 @@
   base::ScopedObservation<LogBuffer, LogBuffer::Observer> observation_{this};
 };
 
-}  // namespace multidevice
+}  // namespace ash::multidevice
 
-}  // namespace chromeos
-
-#endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_MULTIDEVICE_INTERNALS_MULTIDEVICE_INTERNALS_LOGS_HANDLER_H_
+#endif  // CHROME_BROWSER_UI_WEBUI_ASH_MULTIDEVICE_INTERNALS_MULTIDEVICE_INTERNALS_LOGS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_phone_hub_handler.cc b/chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_phone_hub_handler.cc
similarity index 96%
rename from chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_phone_hub_handler.cc
rename to chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_phone_hub_handler.cc
index 384fd57..b870149 100644
--- a/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_phone_hub_handler.cc
+++ b/chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_phone_hub_handler.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/chromeos/multidevice_internals/multidevice_internals_phone_hub_handler.h"
+#include "chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_phone_hub_handler.h"
 
 #include <memory>
 #include <string>
@@ -25,8 +25,7 @@
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/gfx/image/image.h"
 
-namespace chromeos {
-namespace multidevice {
+namespace ash::multidevice {
 
 namespace {
 
@@ -346,7 +345,7 @@
   Profile* profile = Profile::FromWebUI(web_ui());
   auto* phone_hub_manager =
       phonehub::PhoneHubManagerFactory::GetForProfile(profile);
-  ash::SystemTray::Get()->SetPhoneHubManager(phone_hub_manager);
+  SystemTray::Get()->SetPhoneHubManager(phone_hub_manager);
 
   RemoveObservers();
   fake_phone_hub_manager_.reset();
@@ -359,7 +358,7 @@
 
   PA_LOG(VERBOSE) << "Setting fake Phone Hub Manager";
   fake_phone_hub_manager_ = std::make_unique<phonehub::FakePhoneHubManager>();
-  ash::SystemTray::Get()->SetPhoneHubManager(fake_phone_hub_manager_.get());
+  SystemTray::Get()->SetPhoneHubManager(fake_phone_hub_manager_.get());
   AddObservers();
 }
 
@@ -642,7 +641,7 @@
     std::vector<phonehub::CameraRollItem> items;
     // Create items in descending key order
     for (int i = *number_of_thumbnails; i > 0; --i) {
-      ash::phonehub::proto::CameraRollItemMetadata metadata;
+      phonehub::proto::CameraRollItemMetadata metadata;
       metadata.set_key(base::NumberToString(i));
       metadata.set_mime_type(file_type);
       metadata.set_last_modified_millis(1577865600 + i);
@@ -667,23 +666,23 @@
     fake_phone_hub_manager_->fake_camera_roll_manager()
         ->SetSimulatedDownloadError(false);
   } else {
-    ash::phonehub::CameraRollManager::Observer::DownloadErrorType error_type;
+    phonehub::CameraRollManager::Observer::DownloadErrorType error_type;
     switch (*download_result_as_int) {
       case 1:
         download_result = "Generic Error";
-        error_type = ash::phonehub::CameraRollManager::Observer::
-            DownloadErrorType::kGenericError;
+        error_type = phonehub::CameraRollManager::Observer::DownloadErrorType::
+            kGenericError;
         break;
       case 2:
         download_result = "Storage Error";
-        error_type = ash::phonehub::CameraRollManager::Observer::
-            DownloadErrorType::kInsufficientStorage;
+        error_type = phonehub::CameraRollManager::Observer::DownloadErrorType::
+            kInsufficientStorage;
         break;
       case 3:
       default:
         download_result = "Network Error";
-        error_type = ash::phonehub::CameraRollManager::Observer::
-            DownloadErrorType::kNetworkConnection;
+        error_type = phonehub::CameraRollManager::Observer::DownloadErrorType::
+            kNetworkConnection;
         break;
     }
     fake_phone_hub_manager_->fake_camera_roll_manager()
@@ -700,5 +699,4 @@
                   << "\n  Download result: " << download_result;
 }
 
-}  // namespace multidevice
-}  // namespace chromeos
+}  // namespace ash::multidevice
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_phone_hub_handler.h b/chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_phone_hub_handler.h
similarity index 85%
rename from chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_phone_hub_handler.h
rename to chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_phone_hub_handler.h
index 8fa7a6c..f4d88740 100644
--- a/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_phone_hub_handler.h
+++ b/chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_phone_hub_handler.h
@@ -2,13 +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_WEBUI_CHROMEOS_MULTIDEVICE_INTERNALS_MULTIDEVICE_INTERNALS_PHONE_HUB_HANDLER_H_
-#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_MULTIDEVICE_INTERNALS_MULTIDEVICE_INTERNALS_PHONE_HUB_HANDLER_H_
+#ifndef CHROME_BROWSER_UI_WEBUI_ASH_MULTIDEVICE_INTERNALS_MULTIDEVICE_INTERNALS_PHONE_HUB_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_ASH_MULTIDEVICE_INTERNALS_MULTIDEVICE_INTERNALS_PHONE_HUB_HANDLER_H_
 
 #include "ash/components/phonehub/camera_roll_manager.h"
 #include "ash/components/phonehub/do_not_disturb_controller.h"
-// TODO(https://crbug.com/1164001): move to forward declaration.
-#include "ash/components/phonehub/fake_phone_hub_manager.h"
 #include "ash/components/phonehub/find_my_device_controller.h"
 #include "ash/components/phonehub/notification_manager.h"
 #include "ash/components/phonehub/onboarding_ui_tracker.h"
@@ -16,7 +14,12 @@
 #include "base/scoped_observation.h"
 #include "content/public/browser/web_ui_message_handler.h"
 
-namespace chromeos {
+namespace ash {
+
+namespace phonehub {
+class FakePhoneHubManager;
+}
+
 namespace multidevice {
 
 // WebUIMessageHandler for chrome://multidevice-internals PhoneHub section.
@@ -27,7 +30,7 @@
       public phonehub::FindMyDeviceController::Observer,
       public phonehub::TetherController::Observer,
       public phonehub::OnboardingUiTracker::Observer,
-      public ash::phonehub::CameraRollManager::Observer {
+      public phonehub::CameraRollManager::Observer {
  public:
   MultidevicePhoneHubHandler();
   MultidevicePhoneHubHandler(const MultidevicePhoneHubHandler&) = delete;
@@ -97,12 +100,12 @@
   base::ScopedObservation<phonehub::OnboardingUiTracker,
                           phonehub::OnboardingUiTracker::Observer>
       onboarding_ui_tracker_observation_{this};
-  base::ScopedObservation<ash::phonehub::CameraRollManager,
-                          ash::phonehub::CameraRollManager::Observer>
+  base::ScopedObservation<phonehub::CameraRollManager,
+                          phonehub::CameraRollManager::Observer>
       camera_roll_manager_observation_{this};
 };
 
 }  // namespace multidevice
-}  // namespace chromeos
+}  // namespace ash
 
-#endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_MULTIDEVICE_INTERNALS_MULTIDEVICE_INTERNALS_PHONE_HUB_HANDLER_H_
+#endif  // CHROME_BROWSER_UI_WEBUI_ASH_MULTIDEVICE_INTERNALS_MULTIDEVICE_INTERNALS_PHONE_HUB_HANDLER_H_
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_ui.cc b/chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_ui.cc
similarity index 81%
rename from chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_ui.cc
rename to chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_ui.cc
index a1fd7b3..bb0bd28e 100644
--- a/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_ui.cc
+++ b/chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_ui.cc
@@ -2,13 +2,13 @@
 // 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/chromeos/multidevice_internals/multidevice_internals_ui.h"
+#include "chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_ui.h"
 
 #include "ash/constants/ash_features.h"
 #include "base/containers/span.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_logs_handler.h"
-#include "chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_phone_hub_handler.h"
+#include "chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_logs_handler.h"
+#include "chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_phone_hub_handler.h"
 #include "chrome/browser/ui/webui/webui_util.h"
 #include "chrome/common/webui_url_constants.h"
 #include "chrome/grit/multidevice_internals_resources.h"
@@ -17,7 +17,7 @@
 #include "content/public/browser/web_ui_data_source.h"
 #include "ui/base/webui/web_ui_util.h"
 
-namespace chromeos {
+namespace ash {
 
 MultideviceInternalsUI::MultideviceInternalsUI(content::WebUI* web_ui)
     : ui::MojoWebUIController(web_ui, /*enable_chrome_send=*/true) {
@@ -42,4 +42,4 @@
 
 WEB_UI_CONTROLLER_TYPE_IMPL(MultideviceInternalsUI)
 
-}  //  namespace chromeos
+}  // namespace ash
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_ui.h b/chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_ui.h
similarity index 65%
rename from chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_ui.h
rename to chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_ui.h
index 0f99ea40..3a7b1399 100644
--- a/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_ui.h
+++ b/chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_ui.h
@@ -2,12 +2,12 @@
 // 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_CHROMEOS_MULTIDEVICE_INTERNALS_MULTIDEVICE_INTERNALS_UI_H_
-#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_MULTIDEVICE_INTERNALS_MULTIDEVICE_INTERNALS_UI_H_
+#ifndef CHROME_BROWSER_UI_WEBUI_ASH_MULTIDEVICE_INTERNALS_MULTIDEVICE_INTERNALS_UI_H_
+#define CHROME_BROWSER_UI_WEBUI_ASH_MULTIDEVICE_INTERNALS_MULTIDEVICE_INTERNALS_UI_H_
 
 #include "ui/webui/mojo_web_ui_controller.h"
 
-namespace chromeos {
+namespace ash {
 
 // The WebUI controller for chrome://multidevice-internals.
 class MultideviceInternalsUI : public ui::MojoWebUIController {
@@ -21,6 +21,6 @@
   WEB_UI_CONTROLLER_TYPE_DECL();
 };
 
-}  //  namespace chromeos
+}  // namespace ash
 
-#endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_MULTIDEVICE_INTERNALS_MULTIDEVICE_INTERNALS_UI_H_
+#endif  // CHROME_BROWSER_UI_WEBUI_ASH_MULTIDEVICE_INTERNALS_MULTIDEVICE_INTERNALS_UI_H_
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_setup/DIR_METADATA b/chrome/browser/ui/webui/ash/multidevice_setup/DIR_METADATA
similarity index 100%
rename from chrome/browser/ui/webui/chromeos/multidevice_setup/DIR_METADATA
rename to chrome/browser/ui/webui/ash/multidevice_setup/DIR_METADATA
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_setup/OWNERS b/chrome/browser/ui/webui/ash/multidevice_setup/OWNERS
similarity index 100%
rename from chrome/browser/ui/webui/chromeos/multidevice_setup/OWNERS
rename to chrome/browser/ui/webui/ash/multidevice_setup/OWNERS
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.cc b/chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_dialog.cc
similarity index 87%
rename from chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.cc
rename to chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_dialog.cc
index 407dad4..5383173 100644
--- a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.cc
+++ b/chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_dialog.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/chromeos/multidevice_setup/multidevice_setup_dialog.h"
+#include "chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_dialog.h"
 
 #include "ash/constants/ash_features.h"
 #include "ash/public/cpp/shell_window_ids.h"
@@ -18,8 +18,8 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/browser_dialogs.h"
-#include "chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_handler.h"
-#include "chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_localized_strings_provider.h"
+#include "chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_handler.h"
+#include "chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_localized_strings_provider.h"
 #include "chrome/browser/ui/webui/metrics_handler.h"
 #include "chrome/browser/ui/webui/webui_util.h"
 #include "chrome/common/url_constants.h"
@@ -35,9 +35,7 @@
 #include "ui/gfx/native_widget_types.h"
 #include "ui/wm/core/shadow_types.h"
 
-namespace chromeos {
-
-namespace multidevice_setup {
+namespace ash::multidevice_setup {
 
 // static
 MultiDeviceSetupDialog* MultiDeviceSetupDialog::current_instance_ = nullptr;
@@ -62,8 +60,8 @@
 
   // Remove the black backdrop behind the dialog window which appears in tablet
   // and full-screen mode.
-  ash::WindowBackdrop::Get(containing_window_)
-      ->SetBackdropMode(ash::WindowBackdrop::BackdropMode::kDisabled);
+  WindowBackdrop::Get(containing_window_)
+      ->SetBackdropMode(WindowBackdrop::BackdropMode::kDisabled);
 }
 
 // static
@@ -119,7 +117,7 @@
 
   source->DisableTrustedTypesCSP();
 
-  chromeos::multidevice_setup::AddLocalizedStrings(source);
+  AddLocalizedStrings(source);
   source->UseStringsJs();
 
   webui::SetupWebUIDataSource(
@@ -136,8 +134,7 @@
 MultiDeviceSetupDialogUI::~MultiDeviceSetupDialogUI() = default;
 
 void MultiDeviceSetupDialogUI::BindInterface(
-    mojo::PendingReceiver<ash::multidevice_setup::mojom::MultiDeviceSetup>
-        receiver) {
+    mojo::PendingReceiver<mojom::MultiDeviceSetup> receiver) {
   MultiDeviceSetupService* service =
       MultiDeviceSetupServiceFactory::GetForProfile(
           Profile::FromWebUI(web_ui()));
@@ -147,6 +144,4 @@
 
 WEB_UI_CONTROLLER_TYPE_IMPL(MultiDeviceSetupDialogUI)
 
-}  // namespace multidevice_setup
-
-}  // namespace chromeos
+}  // namespace ash::multidevice_setup
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.h b/chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_dialog.h
similarity index 76%
rename from chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.h
rename to chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_dialog.h
index cb298afa..c2b3accd 100644
--- a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.h
+++ b/chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_dialog.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_CHROMEOS_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_DIALOG_H_
-#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_DIALOG_H_
+#ifndef CHROME_BROWSER_UI_WEBUI_ASH_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_DIALOG_H_
+#define CHROME_BROWSER_UI_WEBUI_ASH_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_DIALOG_H_
 
 #include <string>
 #include <vector>
@@ -14,9 +14,7 @@
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "ui/web_dialogs/web_dialog_ui.h"
 
-namespace chromeos {
-
-namespace multidevice_setup {
+namespace ash::multidevice_setup {
 
 // Dialog which displays the multi-device setup flow which allows users to
 // enable features involving communication between multiple devices (e.g., a
@@ -70,24 +68,12 @@
 
   // Instantiates implementor of the mojom::MultiDeviceSetup mojo interface
   // passing the pending receiver that will be internally bound.
-  void BindInterface(
-      mojo::PendingReceiver<ash::multidevice_setup::mojom::MultiDeviceSetup>
-          receiver);
+  void BindInterface(mojo::PendingReceiver<mojom::MultiDeviceSetup> receiver);
 
  private:
   WEB_UI_CONTROLLER_TYPE_DECL();
 };
 
-}  // namespace multidevice_setup
+}  // namespace ash::multidevice_setup
 
-}  // namespace chromeos
-
-// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
-// source migration is finished.
-namespace ash {
-namespace multidevice_setup {
-using ::chromeos::multidevice_setup::MultiDeviceSetupDialog;
-}
-}  // namespace ash
-
-#endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_DIALOG_H_
+#endif  // CHROME_BROWSER_UI_WEBUI_ASH_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_DIALOG_H_
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_handler.cc b/chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_handler.cc
similarity index 87%
rename from chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_handler.cc
rename to chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_handler.cc
index 8c430bc..4739534f 100644
--- a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_handler.cc
+++ b/chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_handler.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/chromeos/multidevice_setup/multidevice_setup_handler.h"
+#include "chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_handler.h"
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
@@ -15,9 +15,7 @@
 #include "components/user_manager/user.h"
 #include "ui/base/webui/web_ui_util.h"
 
-namespace chromeos {
-
-namespace multidevice_setup {
+namespace ash::multidevice_setup {
 
 MultideviceSetupHandler::MultideviceSetupHandler() = default;
 
@@ -43,8 +41,7 @@
   std::string callback_id = args[0].GetString();
 
   const user_manager::User* user =
-      chromeos::ProfileHelper::Get()->GetUserByProfile(
-          Profile::FromWebUI(web_ui()));
+      ProfileHelper::Get()->GetUserByProfile(Profile::FromWebUI(web_ui()));
 
   base::Value::Dict response;
   response.Set("email", user->GetDisplayEmail());
@@ -65,6 +62,4 @@
       chromeos::settings::mojom::kMultiDeviceFeaturesSubpagePath);
 }
 
-}  // namespace multidevice_setup
-
-}  // namespace chromeos
+}  // namespace ash::multidevice_setup
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_handler.h b/chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_handler.h
similarity index 66%
rename from chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_handler.h
rename to chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_handler.h
index c1a8db2..3127b38a 100644
--- a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_handler.h
+++ b/chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_handler.h
@@ -2,14 +2,12 @@
 // 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_CHROMEOS_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_HANDLER_H_
-#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_HANDLER_H_
+#ifndef CHROME_BROWSER_UI_WEBUI_ASH_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_ASH_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_HANDLER_H_
 
 #include "content/public/browser/web_ui_message_handler.h"
 
-namespace chromeos {
-
-namespace multidevice_setup {
+namespace ash::multidevice_setup {
 
 // Chrome MultiDevice setup flow WebUI handler.
 class MultideviceSetupHandler : public content::WebUIMessageHandler {
@@ -29,8 +27,6 @@
   void HandleOpenMultiDeviceSettings(const base::Value::List& args);
 };
 
-}  // namespace multidevice_setup
+}  // namespace ash::multidevice_setup
 
-}  // namespace chromeos
-
-#endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_HANDLER_H_
+#endif  // CHROME_BROWSER_UI_WEBUI_ASH_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_HANDLER_H_
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_localized_strings_provider.cc b/chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_localized_strings_provider.cc
similarity index 80%
rename from chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_localized_strings_provider.cc
rename to chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_localized_strings_provider.cc
index 74f43393..9e7bbac 100644
--- a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_localized_strings_provider.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/chromeos/multidevice_setup/multidevice_setup_localized_strings_provider.h"
+#include "chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_localized_strings_provider.h"
 
 #include "ash/constants/ash_features.h"
 #include "ash/services/multidevice_setup/public/cpp/url_provider.h"
@@ -11,7 +11,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/system/sys_info.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_handler.h"
+#include "chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_handler.h"
 #include "chrome/browser/ui/webui/webui_util.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/common/webui_url_constants.h"
@@ -29,9 +29,7 @@
 #include "ui/base/webui/web_ui_util.h"
 #include "ui/chromeos/devicetype_utils.h"
 
-namespace chromeos {
-
-namespace multidevice_setup {
+namespace ash::multidevice_setup {
 
 namespace {
 
@@ -96,9 +94,7 @@
                 IDS_MULTIDEVICE_SETUP_START_SETUP_PAGE_MESSAGE,
                 ui::GetChromeOSDeviceName(), kFootnoteMarker,
                 base::UTF8ToUTF16(
-                    chromeos::multidevice_setup::
-                        GetBoardSpecificBetterTogetherSuiteLearnMoreUrl()
-                            .spec())));
+                    GetBoardSpecificBetterTogetherSuiteLearnMoreUrl().spec())));
 
         localized_strings.emplace_back(
             "startSetupPageFootnote",
@@ -116,9 +112,8 @@
             "startSetupPageFeatureListAwm",
             l10n_util::GetStringFUTF16(
                 IDS_MULTIDEVICE_SETUP_START_SETUP_PAGE_AWM_DESCRIPTION,
-                base::UTF8ToUTF16(chromeos::multidevice_setup::
-                                      GetBoardSpecificMessagesLearnMoreUrl()
-                                          .spec())));
+                base::UTF8ToUTF16(
+                    GetBoardSpecificMessagesLearnMoreUrl().spec())));
 
         return localized_strings;
       }());
@@ -131,19 +126,16 @@
 void AddLocalizedStrings(content::WebUIDataSource* html_source) {
   html_source->AddLocalizedStrings(kLocalizedStringsWithoutPlaceholders);
 
-  html_source->AddBoolean(
-      "phoneHubEnabled",
-      base::FeatureList::IsEnabled(chromeos::features::kPhoneHub));
+  html_source->AddBoolean("phoneHubEnabled",
+                          base::FeatureList::IsEnabled(features::kPhoneHub));
 
   html_source->AddBoolean(
       "phoneHubCameraRollEnabled",
-      base::FeatureList::IsEnabled(chromeos::features::kPhoneHub) &&
-          base::FeatureList::IsEnabled(
-              chromeos::features::kPhoneHubCameraRoll));
+      base::FeatureList::IsEnabled(features::kPhoneHub) &&
+          base::FeatureList::IsEnabled(features::kPhoneHubCameraRoll));
 
-  html_source->AddBoolean(
-      "wifiSyncEnabled",
-      base::FeatureList::IsEnabled(chromeos::features::kWifiSyncAndroid));
+  html_source->AddBoolean("wifiSyncEnabled", base::FeatureList::IsEnabled(
+                                                 features::kWifiSyncAndroid));
 
   for (const auto& entry : GetLocalizedStringsWithPlaceholders())
     html_source->AddString(entry.name, entry.localized_string);
@@ -163,12 +155,11 @@
   // TODO(crbug.com/964547): Refactor so that any change to these strings will
   // surface in both the OOBE and post-OOBE UIs without having to adjust both
   // localization calls separately.
-  builder->AddF(
-      "startSetupPageMessage", IDS_MULTIDEVICE_SETUP_START_SETUP_PAGE_MESSAGE,
-      ui::GetChromeOSDeviceName(), kFootnoteMarker,
-      base::UTF8ToUTF16(chromeos::multidevice_setup::
-                            GetBoardSpecificBetterTogetherSuiteLearnMoreUrl()
-                                .spec()));
+  builder->AddF("startSetupPageMessage",
+                IDS_MULTIDEVICE_SETUP_START_SETUP_PAGE_MESSAGE,
+                ui::GetChromeOSDeviceName(), kFootnoteMarker,
+                base::UTF8ToUTF16(
+                    GetBoardSpecificBetterTogetherSuiteLearnMoreUrl().spec()));
 
   builder->AddF("startSetupPageFeatureListHeader",
                 IDS_MULTIDEVICE_SETUP_START_SETUP_PAGE_FEATURE_LIST_HEADER,
@@ -181,11 +172,7 @@
   builder->AddF(
       "startSetupPageFeatureListAwm",
       IDS_MULTIDEVICE_SETUP_START_SETUP_PAGE_AWM_DESCRIPTION,
-      base::UTF8ToUTF16(
-          chromeos::multidevice_setup::GetBoardSpecificMessagesLearnMoreUrl()
-              .spec()));
+      base::UTF8ToUTF16(GetBoardSpecificMessagesLearnMoreUrl().spec()));
 }
 
-}  // namespace multidevice_setup
-
-}  // namespace chromeos
+}  // namespace ash::multidevice_setup
diff --git a/chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_localized_strings_provider.h b/chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_localized_strings_provider.h
new file mode 100644
index 0000000..0578ea02
--- /dev/null
+++ b/chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_localized_strings_provider.h
@@ -0,0 +1,31 @@
+// 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_UI_WEBUI_ASH_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_LOCALIZED_STRINGS_PROVIDER_H_
+#define CHROME_BROWSER_UI_WEBUI_ASH_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_LOCALIZED_STRINGS_PROVIDER_H_
+
+namespace login {
+class LocalizedValuesBuilder;
+}
+
+namespace content {
+class WebUIDataSource;
+}
+
+namespace ash::multidevice_setup {
+
+// Adds the strings needed for the MultiDevice setup flow to |html_source|.
+void AddLocalizedStrings(content::WebUIDataSource* html_source);
+
+// Same as AddLocalizedStrings but for a LocalizedValuesBuilder.
+void AddLocalizedValuesToBuilder(::login::LocalizedValuesBuilder* builder);
+
+}  // namespace ash::multidevice_setup
+
+// TODO(https://crbug.com/1164001): remove when the migration is finished.
+namespace chromeos::multidevice_setup {
+using ::ash::multidevice_setup::AddLocalizedValuesToBuilder;
+}
+
+#endif  // CHROME_BROWSER_UI_WEBUI_ASH_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_LOCALIZED_STRINGS_PROVIDER_H_
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 54a6556e..ede9f17 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -264,6 +264,8 @@
 #include "chrome/browser/ui/webui/ash/in_session_password_change/lock_screen_start_reauth_ui.h"
 #include "chrome/browser/ui/webui/ash/in_session_password_change/password_change_ui.h"
 #include "chrome/browser/ui/webui/ash/launcher_internals/launcher_internals_ui.h"
+#include "chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_ui.h"
+#include "chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_dialog.h"
 #include "chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_ui.h"
 #include "chrome/browser/ui/webui/chromeos/bluetooth_pairing_dialog.h"
 #include "chrome/browser/ui/webui/chromeos/certificate_manager_dialog_ui.h"
@@ -274,8 +276,6 @@
 #include "chrome/browser/ui/webui/chromeos/internet_detail_dialog.h"
 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
 #include "chrome/browser/ui/webui/chromeos/manage_mirrorsync/manage_mirrorsync_ui.h"
-#include "chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_ui.h"
-#include "chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.h"
 #include "chrome/browser/ui/webui/chromeos/network_ui.h"
 #include "chrome/browser/ui/webui/chromeos/notification_tester/notification_tester_ui.h"
 #include "chrome/browser/ui/webui/chromeos/parent_access/parent_access_ui.h"
@@ -1024,9 +1024,9 @@
   if (url.host_piece() == chrome::kChromeUIMobileSetupHost)
     return &NewWebUI<ash::cellular_setup::MobileSetupUI>;
   if (url.host_piece() == chrome::kChromeUIMultiDeviceInternalsHost)
-    return &NewWebUI<chromeos::MultideviceInternalsUI>;
+    return &NewWebUI<ash::MultideviceInternalsUI>;
   if (url.host_piece() == chrome::kChromeUIMultiDeviceSetupHost)
-    return &NewWebUI<chromeos::multidevice_setup::MultiDeviceSetupDialogUI>;
+    return &NewWebUI<ash::multidevice_setup::MultiDeviceSetupDialogUI>;
   if (url.host_piece() == chrome::kChromeUINetworkHost)
     return &NewWebUI<chromeos::NetworkUI>;
   if (url.host_piece() == chrome::kChromeUIOobeHost) {
diff --git a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.h b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.h
index 65827a6a..da39115 100644
--- a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.h
+++ b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.h
@@ -93,4 +93,9 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove when it moved to ash.
+namespace ash {
+using ::chromeos::IsHotwordDspAvailable;
+}
+
 #endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_ASSISTANT_OPTIN_ASSISTANT_OPTIN_UTILS_H_
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
index f9c83b1..4bb2aac5 100644
--- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -324,12 +324,7 @@
 
 }  // namespace
 
-GaiaScreenHandler::GaiaScreenHandler(
-    const scoped_refptr<NetworkStateInformer>& network_state_informer)
-    : BaseScreenHandler(kScreenId),
-      network_state_informer_(network_state_informer) {
-  DCHECK(network_state_informer_.get());
-}
+GaiaScreenHandler::GaiaScreenHandler() : BaseScreenHandler(kScreenId) {}
 
 GaiaScreenHandler::~GaiaScreenHandler() {
   if (is_security_token_pin_enabled_)
@@ -563,7 +558,6 @@
 
   was_security_token_pin_canceled_ = false;
 
-  frame_state_ = FRAME_STATE_LOADING;
   CallExternalAPI("loadAuthExtension", std::move(params));
 }
 
@@ -572,7 +566,8 @@
     VLOG(1) << "Skipping reloading of Gaia since gaia is loading.";
     return;
   }
-  NetworkStateInformer::State state = network_state_informer_->state();
+  const NetworkStateInformer::State state =
+      signin_screen_handler_->GetNetworkStateInformerStateForMigration();
   if (state != NetworkStateInformer::ONLINE &&
       !signin_screen_handler_->proxy_auth_dialog_need_reload_) {
     VLOG(1) << "Skipping reloading of Gaia since network state=" << state;
@@ -581,7 +576,6 @@
 
   signin_screen_handler_->proxy_auth_dialog_need_reload_ = false;
   VLOG(1) << "Reloading Gaia.";
-  frame_state_ = FRAME_STATE_LOADING;
   LoadAuthExtension(force_reload);
 }
 
@@ -688,7 +682,6 @@
 
 void GaiaScreenHandler::HandleAuthExtensionLoaded() {
   VLOG(1) << "Auth extension finished loading";
-  auth_extension_being_loaded_ = false;
   // Recreate the client cert usage observer, in order to track only the certs
   // used during the current sign-in attempt.
   extension_provided_client_cert_usage_observer_ =
@@ -926,7 +919,9 @@
   frame_error_ = net::OK;
   frame_state_ = FRAME_STATE_LOADED;
 
-  if (network_state_informer_->state() == NetworkStateInformer::ONLINE)
+  const NetworkStateInformer::State state =
+      signin_screen_handler_->GetNetworkStateInformerStateForMigration();
+  if (state == NetworkStateInformer::ONLINE)
     UpdateState(NetworkError::ERROR_REASON_UPDATE);
 
   if (test_expects_complete_login_)
@@ -1198,8 +1193,7 @@
   // reload gaia then follow the loading case.
   if (frame_state() == GaiaScreenHandler::FRAME_STATE_LOADED) {
     SubmitLoginFormForTest();
-  } else if (frame_state() != GaiaScreenHandler::FRAME_STATE_LOADING &&
-             !auth_extension_being_loaded_) {
+  } else if (frame_state() != GaiaScreenHandler::FRAME_STATE_LOADING) {
     LoginDisplayHost::default_host()->ShowGaiaDialog(EmptyAccountId());
   }
 }
@@ -1286,7 +1280,6 @@
     return;
   }
 
-  std::string active_network_path = network_state_informer_->network_path();
   if (!untrusted_authority_certs_cache_) {
     // Make additional untrusted authority certificates available for client
     // certificate discovery in case a SAML flow is used which requires a client
@@ -1334,12 +1327,12 @@
 
 void GaiaScreenHandler::LoadAuthExtension(bool force) {
   VLOG(1) << "LoadAuthExtension, force: " << force;
-  if (auth_extension_being_loaded_) {
+  if (frame_state_ == FRAME_STATE_LOADING && !force) {
     VLOG(1) << "Skip loading the Auth extension as it's already being loaded";
     return;
   }
 
-  auth_extension_being_loaded_ = true;
+  frame_state_ = FRAME_STATE_LOADING;
   login::GaiaContext context;
   context.force_reload = force;
   context.email = populated_account_id_.GetUserEmail();
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
index c344ff9..e2ce404 100644
--- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
@@ -19,10 +19,8 @@
 #include "chrome/browser/ash/login/saml/public_saml_url_fetcher.h"
 #include "chrome/browser/certificate_provider/security_token_pin_dialog_host.h"
 #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
-#include "chrome/browser/ui/webui/chromeos/login/network_state_informer.h"
 #include "chrome/browser/ui/webui/chromeos/login/online_login_helper.h"
 #include "chrome/browser/ui/webui/chromeos/login/saml_challenge_key_handler.h"
-#include "chromeos/ash/components/network/portal_detector/network_portal_detector.h"
 #include "chromeos/components/security_token_pin/constants.h"
 #include "components/user_manager/user_type.h"
 #include "net/base/net_errors.h"
@@ -37,7 +35,7 @@
 
 namespace network {
 class NSSTempCertsCacheChromeOS;
-}
+}  // namespace network
 
 namespace chromeos {
 class SigninScreenHandler;
@@ -120,8 +118,7 @@
     FRAME_STATE_ERROR
   };
 
-  explicit GaiaScreenHandler(
-      const scoped_refptr<NetworkStateInformer>& network_state_informer);
+  GaiaScreenHandler();
 
   GaiaScreenHandler(const GaiaScreenHandler&) = delete;
   GaiaScreenHandler& operator=(const GaiaScreenHandler&) = delete;
@@ -275,8 +272,8 @@
   // extension reloading, if it has already been loaded.
   void LoadAuthExtension(bool force);
 
-  // TODO(antrim): GaiaScreenHandler should implement
-  // NetworkStateInformer::Observer.
+  // Remainder of NetworkStateInformerObserver. This function will be moved to
+  // GaiaScreen.
   void UpdateState(NetworkError::ErrorReason reason);
 
   // TODO(antrim): remove this dependency.
@@ -319,9 +316,6 @@
   // Latest Gaia frame error.
   net::Error frame_error_ = net::OK;
 
-  // Network state informer used to keep signin screen up.
-  scoped_refptr<NetworkStateInformer> network_state_informer_;
-
   // Account to pre-populate with.
   AccountId populated_account_id_;
 
@@ -361,9 +355,6 @@
   // signin_screen_handler directly.
   SigninScreenHandler* signin_screen_handler_ = nullptr;
 
-  // True if the authentication extension is still loading.
-  bool auth_extension_being_loaded_ = false;
-
   // Makes untrusted authority certificates from device policy available for
   // client certificate discovery.
   std::unique_ptr<network::NSSTempCertsCacheChromeOS>
diff --git a/chrome/browser/ui/webui/chromeos/login/multidevice_setup_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/multidevice_setup_screen_handler.cc
index 3594910e..068a257 100644
--- a/chrome/browser/ui/webui/chromeos/login/multidevice_setup_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/multidevice_setup_screen_handler.cc
@@ -7,7 +7,7 @@
 #include "ash/constants/ash_features.h"
 #include "base/values.h"
 #include "chrome/browser/ash/login/screens/multidevice_setup_screen.h"
-#include "chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_localized_strings_provider.h"
+#include "chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_localized_strings_provider.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/login/localized_values_builder.h"
 
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
index 2e472699..de5122d6 100644
--- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
@@ -437,8 +437,7 @@
   auto password_change_handler =
       std::make_unique<ActiveDirectoryPasswordChangeScreenHandler>();
 
-  AddScreenHandler(
-      std::make_unique<GaiaScreenHandler>(network_state_informer_));
+  AddScreenHandler(std::make_unique<GaiaScreenHandler>());
 
   AddScreenHandler(std::make_unique<SamlConfirmPasswordHandler>());
 
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
index 108f929a..f138d01 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -345,4 +345,9 @@
   return gaia_screen_handler_->frame_error();
 }
 
+NetworkStateInformer::State
+SigninScreenHandler::GetNetworkStateInformerStateForMigration() {
+  return network_state_informer_->state();
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
index cbb98fa..43ea37fe 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
@@ -18,7 +18,6 @@
 #include "chrome/browser/ash/login/error_screens_histogram_helper.h"
 #include "chrome/browser/ash/login/screens/error_screen.h"
 #include "chrome/browser/ash/login/signin_specifics.h"
-#include "chrome/browser/ash/login/ui/login_display.h"
 #include "chrome/browser/ui/webui/chromeos/login/base_webui_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/network_state_informer.h"
 #include "content/public/browser/notification_observer.h"
@@ -27,17 +26,11 @@
 #include "net/base/net_errors.h"
 #include "ui/events/event_handler.h"
 
-namespace ash {
-class LoginDisplayHostMojo;
-
-}  // namespace ash
-
 namespace chromeos {
 
 class GaiaScreenHandler;
 
-// A class that handles the WebUI hooks in sign-in screen in OobeUI and
-// LoginDisplay.
+// A class that handles the WebUI hooks in sign-in screen in OobeUI.
 class SigninScreenHandler
     : public BaseWebUIHandler,
       public content::NotificationObserver,
@@ -69,8 +62,6 @@
 
  private:
   friend class GaiaScreenHandler;
-  friend class ash::LoginDisplayHostMojo;
-  friend class ReportDnsCacheClearedOnUIThread;
 
   void UpdateStateInternal(NetworkError::ErrorReason reason, bool force_update);
   void HideOfflineMessage(NetworkStateInformer::State state,
@@ -110,6 +101,11 @@
   // GAIA.
   void OnErrorScreenHide();
 
+  // This is a helper function to merge SigninScreenHandler with GaiaScreen and
+  // GaiaScreenHandler classes. It will be removed together with the whole
+  // SigninScreenHandler class.
+  NetworkStateInformer::State GetNetworkStateInformerStateForMigration();
+
   // Network state informer used to keep signin screen up.
   scoped_refptr<NetworkStateInformer> network_state_informer_;
 
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_localized_strings_provider.h b/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_localized_strings_provider.h
deleted file mode 100644
index 0938145..0000000
--- a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_localized_strings_provider.h
+++ /dev/null
@@ -1,30 +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_UI_WEBUI_CHROMEOS_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_LOCALIZED_STRINGS_PROVIDER_H_
-#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_LOCALIZED_STRINGS_PROVIDER_H_
-
-namespace login {
-class LocalizedValuesBuilder;
-}
-
-namespace content {
-class WebUIDataSource;
-}
-
-namespace chromeos {
-
-namespace multidevice_setup {
-
-// Adds the strings needed for the MultiDevice setup flow to |html_source|.
-void AddLocalizedStrings(content::WebUIDataSource* html_source);
-
-// Same as AddLocalizedStrings but for a LocalizedValuesBuilder.
-void AddLocalizedValuesToBuilder(::login::LocalizedValuesBuilder* builder);
-
-}  // namespace multidevice_setup
-
-}  // namespace chromeos
-
-#endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_LOCALIZED_STRINGS_PROVIDER_H_
diff --git a/chrome/browser/ui/webui/chromeos/user_image_source.cc b/chrome/browser/ui/webui/chromeos/user_image_source.cc
index 705fa24..f618403 100644
--- a/chrome/browser/ui/webui/chromeos/user_image_source.cc
+++ b/chrome/browser/ui/webui/chromeos/user_image_source.cc
@@ -134,11 +134,6 @@
   }
 
   if (user) {
-    // After the default avatar images are moved to cloud, the user
-    // should have image bytes when using default images.
-    CHECK(!ash::features::IsAvatarsCloudMigrationEnabled() ||
-          !user->HasDefaultImage() || user->has_image_bytes());
-
     if (user->has_image_bytes()) {
       if (user->image_format() == user_manager::UserImage::FORMAT_PNG ||
           user->image_format() == user_manager::UserImage::FORMAT_WEBP) {
diff --git a/chrome/browser/ui/webui/settings/ash/about_section.cc b/chrome/browser/ui/webui/settings/ash/about_section.cc
index 01572b8..84e87d4 100644
--- a/chrome/browser/ui/webui/settings/ash/about_section.cc
+++ b/chrome/browser/ui/webui/settings/ash/about_section.cc
@@ -42,14 +42,15 @@
 #include "ui/base/webui/web_ui_util.h"
 #include "ui/chromeos/devicetype_utils.h"
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
 
-// TODO(https://crbug.com/1164001): remove after migrating to ash.
 namespace mojom {
-using ::ash::settings::mojom::SearchResultDefaultRank;
-using ::ash::settings::mojom::SearchResultIcon;
-using ::ash::settings::mojom::SearchResultType;
+using ::chromeos::settings::mojom::kAboutChromeOsDetailsSubpagePath;
+using ::chromeos::settings::mojom::kAboutChromeOsSectionPath;
+using ::chromeos::settings::mojom::kDetailedBuildInfoSubpagePath;
+using ::chromeos::settings::mojom::Section;
+using ::chromeos::settings::mojom::Setting;
+using ::chromeos::settings::mojom::Subpage;
 }  // namespace mojom
 
 namespace {
@@ -233,12 +234,11 @@
 
   updater.AddSearchTags(GetDiagnosticsAppSearchConcepts());
 
-  if (base::FeatureList::IsEnabled(chromeos::features::kFirmwareUpdaterApp)) {
+  if (base::FeatureList::IsEnabled(features::kFirmwareUpdaterApp)) {
     updater.AddSearchTags(GetFirmwareUpdatesAppSearchConcepts());
   }
 
-  if (base::FeatureList::IsEnabled(
-          chromeos::features::kEnableHostnameSetting)) {
+  if (base::FeatureList::IsEnabled(features::kEnableHostnameSetting)) {
     updater.AddSearchTags(GetDeviceNameSearchConcepts());
   }
 }
@@ -554,5 +554,4 @@
 }
 #endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
 
-}  // namespace settings
-}  // namespace chromeos
+}  // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/ash/about_section.h b/chrome/browser/ui/webui/settings/ash/about_section.h
index 229c00a2..515479a 100644
--- a/chrome/browser/ui/webui/settings/ash/about_section.h
+++ b/chrome/browser/ui/webui/settings/ash/about_section.h
@@ -8,8 +8,6 @@
 #include "base/values.h"
 #include "build/branding_buildflags.h"
 #include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
-// TODO(https://crbug.com/1164001): move to forward declaration
-#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "components/user_manager/user_manager.h"
 
@@ -17,8 +15,9 @@
 class WebUIDataSource;
 }  // namespace content
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
+
+class SearchTagRegistry;
 
 // Provides UI strings and search tags for the settings "About Chrome OS" page.
 class AboutSection : public OsSettingsSection {
@@ -36,10 +35,11 @@
   void AddLoadTimeData(content::WebUIDataSource* html_source) override;
   void AddHandlers(content::WebUI* web_ui) override;
   int GetSectionNameMessageId() const override;
-  mojom::Section GetSection() const override;
-  ash::settings::mojom::SearchResultIcon GetSectionIcon() const override;
+  chromeos::settings::mojom::Section GetSection() const override;
+  mojom::SearchResultIcon GetSectionIcon() const override;
   std::string GetSectionPath() const override;
-  bool LogMetric(mojom::Setting setting, base::Value& value) const override;
+  bool LogMetric(chromeos::settings::mojom::Setting setting,
+                 base::Value& value) const override;
   void RegisterHierarchy(HierarchyGenerator* generator) const override;
 
   // Returns if the auto update toggle should be shown for the active user.
@@ -53,12 +53,6 @@
 #endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
 };
 
-}  // namespace settings
-}  // namespace chromeos
-
-// TODO(https://crbug.com/1164001): remove when it moved to ash.
-namespace ash::settings {
-using ::chromeos::settings::AboutSection;
-}
+}  // namespace ash::settings
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_ABOUT_SECTION_H_
diff --git a/chrome/browser/ui/webui/settings/ash/accessibility_section.cc b/chrome/browser/ui/webui/settings/ash/accessibility_section.cc
index 9ee1032..5627c9d 100644
--- a/chrome/browser/ui/webui/settings/ash/accessibility_section.cc
+++ b/chrome/browser/ui/webui/settings/ash/accessibility_section.cc
@@ -43,14 +43,22 @@
 #include "ui/base/webui/web_ui_util.h"
 #include "ui/chromeos/events/keyboard_layout_util.h"
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
 
-// TODO(https://crbug.com/1164001): remove after migrating to ash.
 namespace mojom {
-using ::ash::settings::mojom::SearchResultDefaultRank;
-using ::ash::settings::mojom::SearchResultIcon;
-using ::ash::settings::mojom::SearchResultType;
+using ::chromeos::settings::mojom::kAccessibilitySectionPath;
+using ::chromeos::settings::mojom::kAudioAndCaptionsSubpagePath;
+using ::chromeos::settings::mojom::kCaptionsSubpagePath;
+using ::chromeos::settings::mojom::kCursorAndTouchpadSubpagePath;
+using ::chromeos::settings::mojom::kDisplayAndMagnificationSubpagePath;
+using ::chromeos::settings::mojom::kKeyboardAndTextInputSubpagePath;
+using ::chromeos::settings::mojom::kManageAccessibilitySubpagePath;
+using ::chromeos::settings::mojom::kSwitchAccessOptionsSubpagePath;
+using ::chromeos::settings::mojom::kTextToSpeechPagePath;
+using ::chromeos::settings::mojom::kTextToSpeechSubpagePath;
+using ::chromeos::settings::mojom::Section;
+using ::chromeos::settings::mojom::Setting;
+using ::chromeos::settings::mojom::Subpage;
 }  // namespace mojom
 
 namespace {
@@ -471,8 +479,8 @@
 }
 
 bool AreTabletNavigationButtonsAllowed() {
-  return ash::features::IsHideShelfControlsInTabletModeEnabled() &&
-         ash::TabletMode::IsBoardTypeMarkedAsTabletCapable();
+  return features::IsHideShelfControlsInTabletModeEnabled() &&
+         TabletMode::IsBoardTypeMarkedAsTabletCapable();
 }
 
 }  // namespace
@@ -491,15 +499,15 @@
 
   pref_change_registrar_.Init(pref_service_);
   pref_change_registrar_.Add(
-      ash::prefs::kAccessibilitySwitchAccessEnabled,
+      prefs::kAccessibilitySwitchAccessEnabled,
       base::BindRepeating(&AccessibilitySection::UpdateSearchTags,
                           base::Unretained(this)));
   pref_change_registrar_.Add(
-      ash::prefs::kAccessibilitySwitchAccessAutoScanEnabled,
+      prefs::kAccessibilitySwitchAccessAutoScanEnabled,
       base::BindRepeating(&AccessibilitySection::UpdateSearchTags,
                           base::Unretained(this)));
   pref_change_registrar_.Add(
-      ash::prefs::kAccessibilityScreenMagnifierEnabled,
+      prefs::kAccessibilityScreenMagnifierEnabled,
       base::BindRepeating(&AccessibilitySection::UpdateSearchTags,
                           base::Unretained(this)));
 
@@ -984,7 +992,7 @@
       base::UmaHistogramEnumeration(
           "ChromeOS.Settings.Accessibility."
           "FullscreenMagnifierMouseFollowingMode",
-          static_cast<ash::MagnifierMouseFollowingMode>(value.GetInt()));
+          static_cast<MagnifierMouseFollowingMode>(value.GetInt()));
       return true;
 
     default:
@@ -1163,8 +1171,7 @@
     updater.RemoveSearchTags(GetA11yLiveCaptionSearchConcepts());
   }
 
-  if (pref_service_->GetBoolean(
-          ash::prefs::kAccessibilityScreenMagnifierEnabled)) {
+  if (pref_service_->GetBoolean(prefs::kAccessibilityScreenMagnifierEnabled)) {
     updater.AddSearchTags(
         GetA11yFullscreenMagnifierFocusFollowingSearchConcepts());
   } else {
@@ -1176,8 +1183,7 @@
     updater.AddSearchTags(GetA11yVisibilitySearchConcepts());
   }
 
-  if (!pref_service_->GetBoolean(
-          ash::prefs::kAccessibilitySwitchAccessEnabled)) {
+  if (!pref_service_->GetBoolean(prefs::kAccessibilitySwitchAccessEnabled)) {
     return;
   }
 
@@ -1185,10 +1191,9 @@
 
   if (IsSwitchAccessTextAllowed() &&
       pref_service_->GetBoolean(
-          ash::prefs::kAccessibilitySwitchAccessAutoScanEnabled)) {
+          prefs::kAccessibilitySwitchAccessAutoScanEnabled)) {
     updater.AddSearchTags(GetA11ySwitchAccessKeyboardSearchConcepts());
   }
 }
 
-}  // namespace settings
-}  // namespace chromeos
+}  // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/ash/accessibility_section.h b/chrome/browser/ui/webui/settings/ash/accessibility_section.h
index 138ae006..524f96c 100644
--- a/chrome/browser/ui/webui/settings/ash/accessibility_section.h
+++ b/chrome/browser/ui/webui/settings/ash/accessibility_section.h
@@ -7,8 +7,6 @@
 
 #include "base/values.h"
 #include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
-// TODO(https://crbug.com/1164001): move to forward declaration
-#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "content/public/browser/tts_controller.h"
 #include "extensions/browser/extension_registry.h"
@@ -20,8 +18,9 @@
 class WebUIDataSource;
 }  // namespace content
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
+
+class SearchTagRegistry;
 
 // Provides UI strings and search tags for Accessibility settings.
 class AccessibilitySection : public OsSettingsSection,
@@ -38,10 +37,11 @@
   void AddLoadTimeData(content::WebUIDataSource* html_source) override;
   void AddHandlers(content::WebUI* web_ui) override;
   int GetSectionNameMessageId() const override;
-  mojom::Section GetSection() const override;
-  ash::settings::mojom::SearchResultIcon GetSectionIcon() const override;
+  chromeos::settings::mojom::Section GetSection() const override;
+  mojom::SearchResultIcon GetSectionIcon() const override;
   std::string GetSectionPath() const override;
-  bool LogMetric(mojom::Setting setting, base::Value& value) const override;
+  bool LogMetric(chromeos::settings::mojom::Setting setting,
+                 base::Value& value) const override;
   void RegisterHierarchy(HierarchyGenerator* generator) const override;
 
   // content::VoicesChangedDelegate:
@@ -63,12 +63,6 @@
   extensions::ExtensionRegistry* extension_registry_ = nullptr;
 };
 
-}  // namespace settings
-}  // namespace chromeos
-
-// TODO(https://crbug.com/1164001): remove when it moved to ash.
-namespace ash::settings {
-using ::chromeos::settings::AccessibilitySection;
-}
+}  // namespace ash::settings
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_ACCESSIBILITY_SECTION_H_
diff --git a/chrome/browser/ui/webui/settings/ash/apps_section.cc b/chrome/browser/ui/webui/settings/ash/apps_section.cc
index eb5559c5..3893b99 100644
--- a/chrome/browser/ui/webui/settings/ash/apps_section.cc
+++ b/chrome/browser/ui/webui/settings/ash/apps_section.cc
@@ -36,14 +36,20 @@
 #include "ui/base/webui/web_ui_util.h"
 #include "ui/chromeos/devicetype_utils.h"
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
 
-// TODO(https://crbug.com/1164001): remove after migrating to ash.
 namespace mojom {
-using ::ash::settings::mojom::SearchResultDefaultRank;
-using ::ash::settings::mojom::SearchResultIcon;
-using ::ash::settings::mojom::SearchResultType;
+using ::chromeos::settings::mojom::kAppDetailsSubpagePath;
+using ::chromeos::settings::mojom::kAppManagementSubpagePath;
+using ::chromeos::settings::mojom::kAppNotificationsSubpagePath;
+using ::chromeos::settings::mojom::kAppsSectionPath;
+using ::chromeos::settings::mojom::kArcVmUsbPreferencesSubpagePath;
+using ::chromeos::settings::mojom::kGooglePlayStoreSubpagePath;
+using ::chromeos::settings::mojom::kPluginVmSharedPathsSubpagePath;
+using ::chromeos::settings::mojom::kPluginVmUsbPreferencesSubpagePath;
+using ::chromeos::settings::mojom::Section;
+using ::chromeos::settings::mojom::Setting;
+using ::chromeos::settings::mojom::Subpage;
 }  // namespace mojom
 
 namespace {
@@ -347,9 +353,9 @@
 
   // Note: The MessageCenterAsh check here is added for unit testing purposes
   // otherwise check statements are not needed in production.
-  if (ash::MessageCenterAsh::Get()) {
-    ash::MessageCenterAsh::Get()->AddObserver(this);
-    OnQuietModeChanged(ash::MessageCenterAsh::Get()->IsQuietMode());
+  if (MessageCenterAsh::Get()) {
+    MessageCenterAsh::Get()->AddObserver(this);
+    OnQuietModeChanged(MessageCenterAsh::Get()->IsQuietMode());
   }
 
   if (arc::IsArcAllowedForProfile(profile)) {
@@ -373,8 +379,8 @@
   // TODO(crbug.com/1237465): observer is never removed because ash::Shell is
   // destroyed first.
   // Note: The MessageCenterAsh check is also added for unit testing purposes.
-  if (ash::MessageCenterAsh::Get()) {
-    ash::MessageCenterAsh::Get()->RemoveObserver(this);
+  if (MessageCenterAsh::Get()) {
+    MessageCenterAsh::Get()->RemoveObserver(this);
   }
 
   if (arc::IsArcAllowedForProfile(profile())) {
@@ -421,8 +427,7 @@
 
   html_source->AddBoolean(
       "showOsSettingsAppNotificationsRow",
-      base::FeatureList::IsEnabled(
-          chromeos::features::kOsSettingsAppNotificationsPage));
+      base::FeatureList::IsEnabled(features::kOsSettingsAppNotificationsPage));
   html_source->AddBoolean("showArcvmManageUsb", arc::IsArcVmEnabled());
 
   html_source->AddBoolean(
@@ -648,7 +653,7 @@
 
   updater.AddSearchTags(GetAppNotificationsSearchConcepts());
 
-  if (!ash::MessageCenterAsh::Get()->IsQuietMode()) {
+  if (!MessageCenterAsh::Get()->IsQuietMode()) {
     updater.AddSearchTags(GetTurnOnAppNotificationSearchConcepts());
     return;
   }
@@ -656,5 +661,4 @@
   updater.AddSearchTags(GetTurnOffAppNotificationSearchConcepts());
 }
 
-}  // namespace settings
-}  // namespace chromeos
+}  // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/ash/apps_section.h b/chrome/browser/ui/webui/settings/ash/apps_section.h
index b62b34c..2bbbab3 100644
--- a/chrome/browser/ui/webui/settings/ash/apps_section.h
+++ b/chrome/browser/ui/webui/settings/ash/apps_section.h
@@ -10,8 +10,6 @@
 #include "chrome/browser/apps/app_service/app_service_proxy_forward.h"
 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
 #include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
-// TODO(https://crbug.com/1164001): move to forward declaration
-#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h"
 #include "components/prefs/pref_change_registrar.h"
 
 class PrefService;
@@ -20,13 +18,14 @@
 class WebUIDataSource;
 }  // namespace content
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
+
+class SearchTagRegistry;
 
 // Provides UI strings and search tags for Apps settings.
 class AppsSection : public OsSettingsSection,
                     public ArcAppListPrefs::Observer,
-                    public ash::MessageCenterAsh::Observer {
+                    public MessageCenterAsh::Observer {
  public:
   AppsSection(Profile* profile,
               SearchTagRegistry* search_tag_registry,
@@ -40,10 +39,11 @@
   void AddLoadTimeData(content::WebUIDataSource* html_source) override;
   void AddHandlers(content::WebUI* web_ui) override;
   int GetSectionNameMessageId() const override;
-  mojom::Section GetSection() const override;
-  ash::settings::mojom::SearchResultIcon GetSectionIcon() const override;
+  chromeos::settings::mojom::Section GetSection() const override;
+  mojom::SearchResultIcon GetSectionIcon() const override;
   std::string GetSectionPath() const override;
-  bool LogMetric(mojom::Setting setting, base::Value& value) const override;
+  bool LogMetric(chromeos::settings::mojom::Setting setting,
+                 base::Value& value) const override;
   void RegisterHierarchy(HierarchyGenerator* generator) const override;
 
   // ArcAppListPrefs::Observer:
@@ -65,12 +65,6 @@
   PrefChangeRegistrar pref_change_registrar_;
 };
 
-}  // namespace settings
-}  // namespace chromeos
-
-// TODO(https://crbug.com/1164001): remove when it moved to ash.
-namespace ash::settings {
-using ::chromeos::settings::AppsSection;
-}
+}  // namespace ash::settings
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_APPS_SECTION_H_
diff --git a/chrome/browser/ui/webui/settings/ash/bluetooth_section.cc b/chrome/browser/ui/webui/settings/ash/bluetooth_section.cc
index eab4e845..7638606 100644
--- a/chrome/browser/ui/webui/settings/ash/bluetooth_section.cc
+++ b/chrome/browser/ui/webui/settings/ash/bluetooth_section.cc
@@ -34,14 +34,16 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/webui/web_ui_util.h"
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
 
-// TODO(https://crbug.com/1164001): remove after migrating to ash.
 namespace mojom {
-using ::ash::settings::mojom::SearchResultDefaultRank;
-using ::ash::settings::mojom::SearchResultIcon;
-using ::ash::settings::mojom::SearchResultType;
+using ::chromeos::settings::mojom::kBluetoothDeviceDetailSubpagePath;
+using ::chromeos::settings::mojom::kBluetoothDevicesSubpagePath;
+using ::chromeos::settings::mojom::kBluetoothSavedDevicesSubpagePath;
+using ::chromeos::settings::mojom::kBluetoothSectionPath;
+using ::chromeos::settings::mojom::Section;
+using ::chromeos::settings::mojom::Setting;
+using ::chromeos::settings::mojom::Subpage;
 }  // namespace mojom
 
 namespace {
@@ -161,7 +163,7 @@
   if (ash::features::IsFastPairEnabled()) {
     pref_change_registrar_->Init(pref_service_);
     pref_change_registrar_->Add(
-        ash::prefs::kFastPairEnabled,
+        prefs::kFastPairEnabled,
         base::BindRepeating(&BluetoothSection::OnFastPairEnabledChanged,
                             base::Unretained(this)));
   }
@@ -333,7 +335,7 @@
 void BluetoothSection::AddHandlers(content::WebUI* web_ui) {
   web_ui->AddMessageHandler(std::make_unique<BluetoothHandler>());
 
-  if (ash::features::IsFastPairEnabled() &&
+  if (features::IsFastPairEnabled() &&
       features::IsFastPairSavedDevicesEnabled()) {
     web_ui->AddMessageHandler(std::make_unique<FastPairSavedDevicesHandler>());
   }
@@ -450,7 +452,7 @@
 
   updater.AddSearchTags(GetBluetoothSearchConcepts());
 
-  if (ash::features::IsFastPairEnabled()) {
+  if (features::IsFastPairEnabled()) {
     if (pref_service_->GetBoolean(ash::prefs::kFastPairEnabled)) {
       updater.AddSearchTags(GetFastPairOnSearchConcepts());
     } else {
@@ -471,5 +473,4 @@
   updater.AddSearchTags(GetBluetoothPairableSearchConcepts());
 }
 
-}  // namespace settings
-}  // namespace chromeos
+}  // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/ash/bluetooth_section.h b/chrome/browser/ui/webui/settings/ash/bluetooth_section.h
index b3644b8..900c36d 100644
--- a/chrome/browser/ui/webui/settings/ash/bluetooth_section.h
+++ b/chrome/browser/ui/webui/settings/ash/bluetooth_section.h
@@ -9,8 +9,6 @@
 #include "base/memory/weak_ptr.h"
 #include "base/values.h"
 #include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
-// TODO(https://crbug.com/1164001): move to forward declaration
-#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h"
 #include "device/bluetooth/bluetooth_adapter.h"
 
 class PrefChangeRegistrar;
@@ -20,8 +18,9 @@
 class WebUIDataSource;
 }  // namespace content
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
+
+class SearchTagRegistry;
 
 // Provides UI strings and search tags for Bluetooth settings. Different search
 // tags are registered depending on whether the device has a Bluetooth chip and
@@ -39,10 +38,11 @@
   void AddLoadTimeData(content::WebUIDataSource* html_source) override;
   void AddHandlers(content::WebUI* web_ui) override;
   int GetSectionNameMessageId() const override;
-  mojom::Section GetSection() const override;
-  ash::settings::mojom::SearchResultIcon GetSectionIcon() const override;
+  chromeos::settings::mojom::Section GetSection() const override;
+  mojom::SearchResultIcon GetSectionIcon() const override;
   std::string GetSectionPath() const override;
-  bool LogMetric(mojom::Setting setting, base::Value& value) const override;
+  bool LogMetric(chromeos::settings::mojom::Setting setting,
+                 base::Value& value) const override;
   void RegisterHierarchy(HierarchyGenerator* generator) const override;
 
   // device::BluetoothAdapter::Observer:
@@ -69,12 +69,6 @@
   base::WeakPtrFactory<BluetoothSection> weak_ptr_factory_{this};
 };
 
-}  // namespace settings
-}  // namespace chromeos
-
-// TODO(https://crbug.com/1164001): remove when it moved to ash.
-namespace ash::settings {
-using ::chromeos::settings::BluetoothSection;
-}
+}  // namespace ash::settings
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_BLUETOOTH_SECTION_H_
diff --git a/chrome/browser/ui/webui/settings/ash/crostini_section.cc b/chrome/browser/ui/webui/settings/ash/crostini_section.cc
index a9044bf3..d1ec956 100644
--- a/chrome/browser/ui/webui/settings/ash/crostini_section.cc
+++ b/chrome/browser/ui/webui/settings/ash/crostini_section.cc
@@ -32,14 +32,22 @@
 #include "ui/base/webui/web_ui_util.h"
 #include "ui/chromeos/devicetype_utils.h"
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
 
-// TODO(https://crbug.com/1164001): remove after migrating to ash.
 namespace mojom {
-using ::ash::settings::mojom::SearchResultDefaultRank;
-using ::ash::settings::mojom::SearchResultIcon;
-using ::ash::settings::mojom::SearchResultType;
+using ::chromeos::settings::mojom::kBruschettaDetailsSubpagePath;
+using ::chromeos::settings::mojom::kBruschettaUsbPreferencesSubpagePath;
+using ::chromeos::settings::mojom::kCrostiniBackupAndRestoreSubpagePath;
+using ::chromeos::settings::mojom::kCrostiniDetailsSubpagePath;
+using ::chromeos::settings::mojom::kCrostiniDevelopAndroidAppsSubpagePath;
+using ::chromeos::settings::mojom::kCrostiniExtraContainersSubpagePath;
+using ::chromeos::settings::mojom::kCrostiniManageSharedFoldersSubpagePath;
+using ::chromeos::settings::mojom::kCrostiniPortForwardingSubpagePath;
+using ::chromeos::settings::mojom::kCrostiniSectionPath;
+using ::chromeos::settings::mojom::kCrostiniUsbPreferencesSubpagePath;
+using ::chromeos::settings::mojom::Section;
+using ::chromeos::settings::mojom::Setting;
+using ::chromeos::settings::mojom::Subpage;
 }  // namespace mojom
 
 namespace {
@@ -393,8 +401,7 @@
   };
   html_source->AddLocalizedStrings(kLocalizedStrings);
 
-  if (base::FeatureList::IsEnabled(
-          chromeos::features::kCrostiniBullseyeUpgrade)) {
+  if (base::FeatureList::IsEnabled(features::kCrostiniBullseyeUpgrade)) {
     html_source->AddString(
         "crostiniContainerUpgrade",
         l10n_util::GetStringUTF16(
@@ -484,7 +491,7 @@
   html_source->AddBoolean("showCrostiniExtraContainers",
                           IsMultiContainerAllowed());
   html_source->AddBoolean("isOwnerProfile",
-                          chromeos::ProfileHelper::IsOwnerProfile(profile_));
+                          ProfileHelper::IsOwnerProfile(profile_));
   html_source->AddBoolean("isEnterpriseManaged",
                           IsDeviceManaged() || IsProfileManaged(profile_));
   html_source->AddBoolean("showCrostiniContainerUpgrade",
@@ -665,5 +672,4 @@
   // TODO(crbug:1261319): search concepts for extras containers.
 }
 
-}  // namespace settings
-}  // namespace chromeos
+}  // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/ash/crostini_section.h b/chrome/browser/ui/webui/settings/ash/crostini_section.h
index 5898f7e3..ed96156 100644
--- a/chrome/browser/ui/webui/settings/ash/crostini_section.h
+++ b/chrome/browser/ui/webui/settings/ash/crostini_section.h
@@ -7,16 +7,15 @@
 
 #include "base/values.h"
 #include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
-// TODO(https://crbug.com/1164001): move to forward declaration
-#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h"
 #include "components/prefs/pref_change_registrar.h"
 
 namespace content {
 class WebUIDataSource;
 }  // namespace content
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
+
+class SearchTagRegistry;
 
 // Provides UI strings and search tags for Crostini settings. Search tags are
 // only added if Crostini is available, and subpage search tags are added only
@@ -33,10 +32,11 @@
   void AddLoadTimeData(content::WebUIDataSource* html_source) override;
   void AddHandlers(content::WebUI* web_ui) override;
   int GetSectionNameMessageId() const override;
-  mojom::Section GetSection() const override;
-  ash::settings::mojom::SearchResultIcon GetSectionIcon() const override;
+  chromeos::settings::mojom::Section GetSection() const override;
+  mojom::SearchResultIcon GetSectionIcon() const override;
   std::string GetSectionPath() const override;
-  bool LogMetric(mojom::Setting setting, base::Value& value) const override;
+  bool LogMetric(chromeos::settings::mojom::Setting setting,
+                 base::Value& value) const override;
   void RegisterHierarchy(HierarchyGenerator* generator) const override;
 
   bool IsExportImportAllowed() const;
@@ -51,12 +51,6 @@
   Profile* const profile_;
 };
 
-}  // namespace settings
-}  // namespace chromeos
-
-// TODO(https://crbug.com/1164001): remove when it moved to ash.
-namespace ash::settings {
-using ::chromeos::settings::CrostiniSection;
-}
+}  // namespace ash::settings
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_CROSTINI_SECTION_H_
diff --git a/chrome/browser/ui/webui/settings/ash/date_time_section.cc b/chrome/browser/ui/webui/settings/ash/date_time_section.cc
index cc3e36b..9e8c392 100644
--- a/chrome/browser/ui/webui/settings/ash/date_time_section.cc
+++ b/chrome/browser/ui/webui/settings/ash/date_time_section.cc
@@ -22,14 +22,14 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/webui/web_ui_util.h"
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
 
-// TODO(https://crbug.com/1164001): remove after migrating to ash.
 namespace mojom {
-using ::ash::settings::mojom::SearchResultDefaultRank;
-using ::ash::settings::mojom::SearchResultIcon;
-using ::ash::settings::mojom::SearchResultType;
+using ::chromeos::settings::mojom::kDateAndTimeSectionPath;
+using ::chromeos::settings::mojom::kTimeZoneSubpagePath;
+using ::chromeos::settings::mojom::Section;
+using ::chromeos::settings::mojom::Setting;
+using ::chromeos::settings::mojom::Subpage;
 }  // namespace mojom
 
 namespace {
@@ -80,7 +80,7 @@
 
 bool IsFineGrainedTimeZoneEnabled() {
   SystemSettingsProvider provider;
-  return provider.Get(chromeos::kFineGrainedTimeZoneResolveEnabled)->GetBool();
+  return provider.Get(kFineGrainedTimeZoneResolveEnabled)->GetBool();
 }
 
 }  // namespace
@@ -186,5 +186,4 @@
   }
 }
 
-}  // namespace settings
-}  // namespace chromeos
+}  // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/ash/date_time_section.h b/chrome/browser/ui/webui/settings/ash/date_time_section.h
index 93b3f410..5e4cfa4a 100644
--- a/chrome/browser/ui/webui/settings/ash/date_time_section.h
+++ b/chrome/browser/ui/webui/settings/ash/date_time_section.h
@@ -7,15 +7,14 @@
 
 #include "base/values.h"
 #include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
-// TODO(https://crbug.com/1164001): move to forward declaration
-#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h"
 
 namespace content {
 class WebUIDataSource;
 }  // namespace content
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
+
+class SearchTagRegistry;
 
 // Provides UI strings and search tags for Date and Time settings.
 class DateTimeSection : public OsSettingsSection {
@@ -28,19 +27,14 @@
   void AddLoadTimeData(content::WebUIDataSource* html_source) override;
   void AddHandlers(content::WebUI* web_ui) override;
   int GetSectionNameMessageId() const override;
-  mojom::Section GetSection() const override;
-  ash::settings::mojom::SearchResultIcon GetSectionIcon() const override;
+  chromeos::settings::mojom::Section GetSection() const override;
+  mojom::SearchResultIcon GetSectionIcon() const override;
   std::string GetSectionPath() const override;
-  bool LogMetric(mojom::Setting setting, base::Value& value) const override;
+  bool LogMetric(chromeos::settings::mojom::Setting setting,
+                 base::Value& value) const override;
   void RegisterHierarchy(HierarchyGenerator* generator) const override;
 };
 
-}  // namespace settings
-}  // namespace chromeos
-
-// TODO(https://crbug.com/1164001): remove when it moved to ash.
-namespace ash::settings {
-using ::chromeos::settings::DateTimeSection;
-}
+}  // namespace ash::settings
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_DATE_TIME_SECTION_H_
diff --git a/chrome/browser/ui/webui/settings/ash/device_section.cc b/chrome/browser/ui/webui/settings/ash/device_section.cc
index 516b220..e77b911 100644
--- a/chrome/browser/ui/webui/settings/ash/device_section.cc
+++ b/chrome/browser/ui/webui/settings/ash/device_section.cc
@@ -38,14 +38,21 @@
 #include "ui/display/manager/touch_device_manager.h"
 #include "ui/events/devices/device_data_manager.h"
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
 
-// TODO(https://crbug.com/1164001): remove after migrating to ash.
 namespace mojom {
-using ::ash::settings::mojom::SearchResultDefaultRank;
-using ::ash::settings::mojom::SearchResultIcon;
-using ::ash::settings::mojom::SearchResultType;
+using ::chromeos::settings::mojom::kAudioSubpagePath;
+using ::chromeos::settings::mojom::kDeviceSectionPath;
+using ::chromeos::settings::mojom::kDisplaySubpagePath;
+using ::chromeos::settings::mojom::kExternalStorageSubpagePath;
+using ::chromeos::settings::mojom::kKeyboardSubpagePath;
+using ::chromeos::settings::mojom::kPointersSubpagePath;
+using ::chromeos::settings::mojom::kPowerSubpagePath;
+using ::chromeos::settings::mojom::kStorageSubpagePath;
+using ::chromeos::settings::mojom::kStylusSubpagePath;
+using ::chromeos::settings::mojom::Section;
+using ::chromeos::settings::mojom::Setting;
+using ::chromeos::settings::mojom::Subpage;
 }  // namespace mojom
 
 namespace {
@@ -522,8 +529,7 @@
 }
 
 bool AreScrollSettingsAllowed() {
-  return base::FeatureList::IsEnabled(
-      ::chromeos::features::kAllowScrollSettings);
+  return base::FeatureList::IsEnabled(ash::features::kAllowScrollSettings);
 }
 
 bool IsUnifiedDesktopAvailable() {
@@ -611,7 +617,7 @@
   html_source->AddLocalizedStrings(kStylusStrings);
 
   html_source->AddBoolean("hasInternalStylus",
-                          ash::stylus_utils::HasInternalStylus());
+                          stylus_utils::HasInternalStylus());
 }
 
 void AddDeviceDisplayStrings(content::WebUIDataSource* html_source) {
@@ -836,7 +842,8 @@
   if (features::ShouldShowExternalStorageSettings(profile))
     updater.AddSearchTags(GetExternalStorageSearchConcepts());
 
-  PowerManagerClient* power_manager_client = PowerManagerClient::Get();
+  chromeos::PowerManagerClient* power_manager_client =
+      chromeos::PowerManagerClient::Get();
   if (power_manager_client) {
     power_manager_client->AddObserver(this);
 
@@ -864,7 +871,7 @@
   UpdateStylusSearchTags();
 
   // Display search tags are added/removed dynamically.
-  ash::BindCrosDisplayConfigController(
+  BindCrosDisplayConfigController(
       cros_display_config_.BindNewPipeAndPassReceiver());
   mojo::PendingAssociatedRemote<crosapi::mojom::CrosDisplayConfigObserver>
       observer;
@@ -874,12 +881,12 @@
   OnDisplayConfigChanged();
 
   // Night Light settings are added/removed dynamically.
-  ash::NightLightController* night_light_controller =
-      ash::NightLightController::GetInstance();
+  NightLightController* night_light_controller =
+      NightLightController::GetInstance();
   if (night_light_controller) {
-    ash::NightLightController::GetInstance()->AddObserver(this);
+    NightLightController::GetInstance()->AddObserver(this);
     OnNightLightEnabledChanged(
-        ash::NightLightController::GetInstance()->GetEnabled());
+        NightLightController::GetInstance()->GetEnabled());
   }
 }
 
@@ -887,12 +894,13 @@
   pointer_device_observer_.RemoveObserver(this);
   ui::DeviceDataManager::GetInstance()->RemoveObserver(this);
 
-  PowerManagerClient* power_manager_client = PowerManagerClient::Get();
+  chromeos::PowerManagerClient* power_manager_client =
+      chromeos::PowerManagerClient::Get();
   if (power_manager_client)
     power_manager_client->RemoveObserver(this);
 
-  ash::NightLightController* night_light_controller =
-      ash::NightLightController::GetInstance();
+  NightLightController* night_light_controller =
+      NightLightController::GetInstance();
   if (night_light_controller)
     night_light_controller->RemoveObserver(this);
 }
@@ -1077,7 +1085,7 @@
 
   if (exists) {
     updater.AddSearchTags(GetTouchpadSearchConcepts());
-    if (base::FeatureList::IsEnabled(chromeos::features::kAllowScrollSettings))
+    if (base::FeatureList::IsEnabled(ash::features::kAllowScrollSettings))
       updater.AddSearchTags(GetTouchpadScrollAccelerationSearchConcepts());
   }
 }
@@ -1229,17 +1237,18 @@
     updater.RemoveSearchTags(GetDisplayTouchCalibrationSearchConcepts());
 
   // Night Light on settings.
-  if (ash::NightLightController::GetInstance()->GetEnabled())
+  if (NightLightController::GetInstance()->GetEnabled())
     updater.AddSearchTags(GetDisplayNightLightOnSearchConcepts());
   else
     updater.RemoveSearchTags(GetDisplayNightLightOnSearchConcepts());
 }
 
 void DeviceSection::OnGotSwitchStates(
-    absl::optional<PowerManagerClient::SwitchStates> result) {
+    absl::optional<chromeos::PowerManagerClient::SwitchStates> result) {
   SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
 
-  if (result && result->lid_state != PowerManagerClient::LidState::NOT_PRESENT)
+  if (result &&
+      result->lid_state != chromeos::PowerManagerClient::LidState::NOT_PRESENT)
     updater.AddSearchTags(GetPowerWithLaptopLidSearchConcepts());
 }
 
@@ -1253,7 +1262,7 @@
   // TODO(https://crbug.com/1071905): Only show stylus settings if a stylus has
   // been set up. HasStylusInput() will return true for any stylus-compatible
   // device, even if it doesn't have a stylus.
-  if (ash::stylus_utils::HasStylusInput())
+  if (stylus_utils::HasStylusInput())
     updater.AddSearchTags(GetStylusSearchConcepts());
   else
     updater.RemoveSearchTags(GetStylusSearchConcepts());
@@ -1320,5 +1329,4 @@
       base::FeatureList::IsEnabled(ash::features::kAudioSettingsPage));
 }
 
-}  // namespace settings
-}  // namespace chromeos
+}  // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/ash/device_section.h b/chrome/browser/ui/webui/settings/ash/device_section.h
index 491559d..2538eeb 100644
--- a/chrome/browser/ui/webui/settings/ash/device_section.h
+++ b/chrome/browser/ui/webui/settings/ash/device_section.h
@@ -12,8 +12,6 @@
 #include "base/values.h"
 #include "chrome/browser/ash/system/pointer_device_observer.h"
 #include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
-// TODO(https://crbug.com/1164001): move to forward declaration
-#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h"
 #include "chromeos/crosapi/mojom/cros_display_config.mojom.h"
 #include "chromeos/dbus/power/power_manager_client.h"
 #include "mojo/public/cpp/bindings/associated_receiver.h"
@@ -27,16 +25,17 @@
 class WebUIDataSource;
 }  // namespace content
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
+
+class SearchTagRegistry;
 
 // Provides UI strings and search tags for Device settings.
 class DeviceSection : public OsSettingsSection,
                       public system::PointerDeviceObserver::Observer,
                       public ui::InputDeviceEventObserver,
-                      public ash::NightLightController::Observer,
+                      public NightLightController::Observer,
                       public crosapi::mojom::CrosDisplayConfigObserver,
-                      public PowerManagerClient::Observer {
+                      public chromeos::PowerManagerClient::Observer {
  public:
   DeviceSection(Profile* profile,
                 SearchTagRegistry* search_tag_registry,
@@ -48,10 +47,11 @@
   void AddLoadTimeData(content::WebUIDataSource* html_source) override;
   void AddHandlers(content::WebUI* web_ui) override;
   int GetSectionNameMessageId() const override;
-  mojom::Section GetSection() const override;
-  ash::settings::mojom::SearchResultIcon GetSectionIcon() const override;
+  chromeos::settings::mojom::Section GetSection() const override;
+  mojom::SearchResultIcon GetSectionIcon() const override;
   std::string GetSectionPath() const override;
-  bool LogMetric(mojom::Setting setting, base::Value& value) const override;
+  bool LogMetric(chromeos::settings::mojom::Setting setting,
+                 base::Value& value) const override;
   void RegisterHierarchy(HierarchyGenerator* generator) const override;
 
   // system::PointerDeviceObserver::Observer:
@@ -63,17 +63,17 @@
   // ui::InputDeviceObserver:
   void OnDeviceListsComplete() override;
 
-  // ash::NightLightController::Observer:
+  // NightLightController::Observer:
   void OnNightLightEnabledChanged(bool enabled) override;
 
-  // ash::mojom::CrosDisplayConfigObserver
+  // mojom::CrosDisplayConfigObserver
   void OnDisplayConfigChanged() override;
 
-  // PowerManagerClient::Observer:
+  // chromeos::PowerManagerClient::Observer:
   void PowerChanged(const power_manager::PowerSupplyProperties& proto) override;
 
   void OnGotSwitchStates(
-      absl::optional<PowerManagerClient::SwitchStates> result);
+      absl::optional<chromeos::PowerManagerClient::SwitchStates> result);
 
   void UpdateStylusSearchTags();
 
@@ -94,12 +94,6 @@
   base::WeakPtrFactory<DeviceSection> weak_ptr_factory_{this};
 };
 
-}  // namespace settings
-}  // namespace chromeos
-
-// TODO(https://crbug.com/1164001): remove when it moved to ash.
-namespace ash::settings {
-using ::chromeos::settings::DeviceSection;
-}
+}  // namespace ash::settings
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_DEVICE_SECTION_H_
diff --git a/chrome/browser/ui/webui/settings/ash/device_storage_util.cc b/chrome/browser/ui/webui/settings/ash/device_storage_util.cc
index 157cbed..427f185 100644
--- a/chrome/browser/ui/webui/settings/ash/device_storage_util.cc
+++ b/chrome/browser/ui/webui/settings/ash/device_storage_util.cc
@@ -9,7 +9,7 @@
 
 #include "base/notreached.h"
 
-namespace chromeos::settings {
+namespace ash::settings {
 
 int64_t RoundByteSize(int64_t bytes) {
   if (bytes < 0) {
@@ -36,4 +36,4 @@
   return bytes;
 }
 
-}  // namespace chromeos::settings
+}  // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/ash/device_storage_util.h b/chrome/browser/ui/webui/settings/ash/device_storage_util.h
index f4c4a4b..e5e1adb 100644
--- a/chrome/browser/ui/webui/settings/ash/device_storage_util.h
+++ b/chrome/browser/ui/webui/settings/ash/device_storage_util.h
@@ -7,7 +7,7 @@
 
 #include <cstdint>
 
-namespace chromeos::settings {
+namespace ash::settings {
 
 // Round |bytes| to the next power of 2, where the next power of 2 is greater
 // than or equal to |bytes|.
@@ -15,11 +15,6 @@
 // RoundByteSize(4) will return 4.
 int64_t RoundByteSize(int64_t bytes);
 
-}  // namespace chromeos::settings
-
-// TODO(https://crbug.com/1164001): remove when it moved to ash.
-namespace ash::settings {
-using ::chromeos::settings::RoundByteSize;
-}
+}  // namespace ash::settings
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_DEVICE_STORAGE_UTIL_H_
diff --git a/chrome/browser/ui/webui/settings/ash/files_section.cc b/chrome/browser/ui/webui/settings/ash/files_section.cc
index c839803..4da5a9c0 100644
--- a/chrome/browser/ui/webui/settings/ash/files_section.cc
+++ b/chrome/browser/ui/webui/settings/ash/files_section.cc
@@ -18,14 +18,14 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/webui/web_ui_util.h"
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
 
-// TODO(https://crbug.com/1164001): remove after migrating to ash.
 namespace mojom {
-using ::ash::settings::mojom::SearchResultDefaultRank;
-using ::ash::settings::mojom::SearchResultIcon;
-using ::ash::settings::mojom::SearchResultType;
+using ::chromeos::settings::mojom::kFilesSectionPath;
+using ::chromeos::settings::mojom::kNetworkFileSharesSubpagePath;
+using ::chromeos::settings::mojom::Section;
+using ::chromeos::settings::mojom::Setting;
+using ::chromeos::settings::mojom::Subpage;
 }  // namespace mojom
 
 namespace {
@@ -102,7 +102,7 @@
                          GetHelpUrlWithBoard(chrome::kSmbSharesLearnMoreURL));
 
   const user_manager::User* user =
-      chromeos::ProfileHelper::Get()->GetUserByProfile(profile());
+      ProfileHelper::Get()->GetUserByProfile(profile());
   html_source->AddBoolean("isActiveDirectoryUser",
                           user && user->IsActiveDirectoryUser());
 }
@@ -143,5 +143,4 @@
       mojom::kNetworkFileSharesSubpagePath);
 }
 
-}  // namespace settings
-}  // namespace chromeos
+}  // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/ash/files_section.h b/chrome/browser/ui/webui/settings/ash/files_section.h
index 2efaa118..d974553 100644
--- a/chrome/browser/ui/webui/settings/ash/files_section.h
+++ b/chrome/browser/ui/webui/settings/ash/files_section.h
@@ -7,15 +7,14 @@
 
 #include "base/values.h"
 #include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
-// TODO(https://crbug.com/1164001): move to forward declaration
-#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h"
 
 namespace content {
 class WebUIDataSource;
 }  // namespace content
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
+
+class SearchTagRegistry;
 
 // Provides UI strings and search tags for Files settings.
 class FilesSection : public OsSettingsSection {
@@ -28,19 +27,14 @@
   void AddLoadTimeData(content::WebUIDataSource* html_source) override;
   void AddHandlers(content::WebUI* web_ui) override;
   int GetSectionNameMessageId() const override;
-  mojom::Section GetSection() const override;
-  ash::settings::mojom::SearchResultIcon GetSectionIcon() const override;
+  chromeos::settings::mojom::Section GetSection() const override;
+  mojom::SearchResultIcon GetSectionIcon() const override;
   std::string GetSectionPath() const override;
-  bool LogMetric(mojom::Setting setting, base::Value& value) const override;
+  bool LogMetric(chromeos::settings::mojom::Setting setting,
+                 base::Value& value) const override;
   void RegisterHierarchy(HierarchyGenerator* generator) const override;
 };
 
-}  // namespace settings
-}  // namespace chromeos
-
-// TODO(https://crbug.com/1164001): remove when it moved to ash.
-namespace ash::settings {
-using ::chromeos::settings::FilesSection;
-}
+}  // namespace ash::settings
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_FILES_SECTION_H_
diff --git a/chrome/browser/ui/webui/settings/ash/hierarchy.h b/chrome/browser/ui/webui/settings/ash/hierarchy.h
index 86d722e..d930462 100644
--- a/chrome/browser/ui/webui/settings/ash/hierarchy.h
+++ b/chrome/browser/ui/webui/settings/ash/hierarchy.h
@@ -175,4 +175,9 @@
 
 }  // namespace ash::settings
 
+// TODO(https://crbug.com/1164001): remove when the migration is finished.
+namespace chromeos::settings {
+using ::ash::settings::Hierarchy;
+}
+
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_HIERARCHY_H_
diff --git a/chrome/browser/ui/webui/settings/ash/internet_section.cc b/chrome/browser/ui/webui/settings/ash/internet_section.cc
index 54e44e6..3191b3e 100644
--- a/chrome/browser/ui/webui/settings/ash/internet_section.cc
+++ b/chrome/browser/ui/webui/settings/ash/internet_section.cc
@@ -32,14 +32,27 @@
 #include "ui/chromeos/strings/grit/ui_chromeos_strings.h"
 #include "ui/chromeos/strings/network_element_localized_strings_provider.h"
 
-namespace chromeos {
-namespace settings {
-
 // TODO(https://crbug.com/1164001): remove after migrating to ash.
+namespace ash::network_config {
+namespace mojom = chromeos::network_config::mojom;
+}
+
+namespace ash::settings {
+
 namespace mojom {
-using ::ash::settings::mojom::SearchResultDefaultRank;
-using ::ash::settings::mojom::SearchResultIcon;
-using ::ash::settings::mojom::SearchResultType;
+using ::chromeos::settings::mojom::kCellularDetailsSubpagePath;
+using ::chromeos::settings::mojom::kCellularNetworksSubpagePath;
+using ::chromeos::settings::mojom::kEthernetDetailsSubpagePath;
+using ::chromeos::settings::mojom::kKnownNetworksSubpagePath;
+using ::chromeos::settings::mojom::kMobileDataNetworksSubpagePath;
+using ::chromeos::settings::mojom::kNetworkSectionPath;
+using ::chromeos::settings::mojom::kTetherDetailsSubpagePath;
+using ::chromeos::settings::mojom::kVpnDetailsSubpagePath;
+using ::chromeos::settings::mojom::kWifiDetailsSubpagePath;
+using ::chromeos::settings::mojom::kWifiNetworksSubpagePath;
+using ::chromeos::settings::mojom::Section;
+using ::chromeos::settings::mojom::Setting;
+using ::chromeos::settings::mojom::Subpage;
 }  // namespace mojom
 
 namespace {
@@ -608,8 +621,7 @@
   updater.AddSearchTags(GetNetworkSearchConcepts());
 
   // Receive updates when devices (e.g., Ethernet, Wi-Fi) go on/offline.
-  ash::GetNetworkConfigService(
-      cros_network_config_.BindNewPipeAndPassReceiver());
+  GetNetworkConfigService(cros_network_config_.BindNewPipeAndPassReceiver());
   cros_network_config_->AddObserver(receiver_.BindNewPipeAndPassRemote());
 
   // Fetch initial list of devices and active networks.
@@ -850,13 +862,13 @@
   ui::network_element::AddErrorLocalizedStrings(html_source);
   cellular_setup::AddNonStringLoadTimeData(html_source);
   cellular_setup::AddLocalizedStrings(html_source);
-  chromeos::network_health::AddResources(html_source);
-  chromeos::traffic_counters::AddResources(html_source);
+  network_health::AddResources(html_source);
+  traffic_counters::AddResources(html_source);
 
   html_source->AddBoolean(
       "bypassConnectivityCheck",
       base::FeatureList::IsEnabled(
-          ash::features::kCellularBypassESimInstallationConnectivityCheck));
+          features::kCellularBypassESimInstallationConnectivityCheck));
   html_source->AddBoolean("showTechnologyBadge",
                           !ash::features::IsSeparateNetworkIconsEnabled());
   html_source->AddBoolean("captivePortalUI2022",
@@ -1245,5 +1257,4 @@
   }
 }
 
-}  // namespace settings
-}  // namespace chromeos
+}  // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/ash/internet_section.h b/chrome/browser/ui/webui/settings/ash/internet_section.h
index 89d7ec4..53b6b60 100644
--- a/chrome/browser/ui/webui/settings/ash/internet_section.h
+++ b/chrome/browser/ui/webui/settings/ash/internet_section.h
@@ -10,8 +10,6 @@
 
 #include "base/values.h"
 #include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
-// TODO(https://crbug.com/1164001): move to forward declaration
-#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h"
 #include "chromeos/services/network_config/public/cpp/cros_network_config_observer.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
@@ -23,8 +21,9 @@
 class WebUIDataSource;
 }  // namespace content
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
+
+class SearchTagRegistry;
 
 class InternetSection : public OsSettingsSection,
                         public network_config::CrosNetworkConfigObserver {
@@ -37,31 +36,35 @@
   void AddLoadTimeData(content::WebUIDataSource* html_source) override;
   void AddHandlers(content::WebUI* web_ui) override;
   int GetSectionNameMessageId() const override;
-  mojom::Section GetSection() const override;
-  ash::settings::mojom::SearchResultIcon GetSectionIcon() const override;
+  chromeos::settings::mojom::Section GetSection() const override;
+  mojom::SearchResultIcon GetSectionIcon() const override;
   std::string GetSectionPath() const override;
-  bool LogMetric(mojom::Setting setting, base::Value& value) const override;
+  bool LogMetric(chromeos::settings::mojom::Setting setting,
+                 base::Value& value) const override;
   void RegisterHierarchy(HierarchyGenerator* generator) const override;
   std::string ModifySearchResultUrl(
-      ash::settings::mojom::SearchResultType type,
+      mojom::SearchResultType type,
       OsSettingsIdentifier id,
       const std::string& url_to_modify) const override;
 
   // network_config::CrosNetworkConfigObserver:
   void OnActiveNetworksChanged(
-      std::vector<network_config::mojom::NetworkStatePropertiesPtr> networks)
-      override;
+      std::vector<chromeos::network_config::mojom::NetworkStatePropertiesPtr>
+          networks) override;
   void OnDeviceStateListChanged() override;
 
   void FetchDeviceList();
-  void OnGlobalPolicy(network_config::mojom::GlobalPolicyPtr global_policy);
+  void OnGlobalPolicy(
+      chromeos::network_config::mojom::GlobalPolicyPtr global_policy);
   void OnDeviceList(
-      network_config::mojom::GlobalPolicyPtr global_policy,
-      std::vector<network_config::mojom::DeviceStatePropertiesPtr> devices);
+      chromeos::network_config::mojom::GlobalPolicyPtr global_policy,
+      std::vector<chromeos::network_config::mojom::DeviceStatePropertiesPtr>
+          devices);
 
   void FetchNetworkList();
   void OnNetworkList(
-      std::vector<network_config::mojom::NetworkStatePropertiesPtr> networks);
+      std::vector<chromeos::network_config::mojom::NetworkStatePropertiesPtr>
+          networks);
 
   // Null if no active cellular network exists. The active cellular network
   // corresponds to the currently active SIM slot, and may not be
@@ -78,17 +81,12 @@
 
   bool does_ethernet_device_exist_ = false;
 
-  mojo::Receiver<network_config::mojom::CrosNetworkConfigObserver> receiver_{
-      this};
-  mojo::Remote<network_config::mojom::CrosNetworkConfig> cros_network_config_;
+  mojo::Receiver<chromeos::network_config::mojom::CrosNetworkConfigObserver>
+      receiver_{this};
+  mojo::Remote<chromeos::network_config::mojom::CrosNetworkConfig>
+      cros_network_config_;
 };
 
-}  // namespace settings
-}  // namespace chromeos
-
-// TODO(https://crbug.com/1164001): remove when it moved to ash.
-namespace ash::settings {
-using ::chromeos::settings::InternetSection;
-}
+}  // namespace ash::settings
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_INTERNET_SECTION_H_
diff --git a/chrome/browser/ui/webui/settings/ash/kerberos_section.cc b/chrome/browser/ui/webui/settings/ash/kerberos_section.cc
index ba4d1a7..11b88f4 100644
--- a/chrome/browser/ui/webui/settings/ash/kerberos_section.cc
+++ b/chrome/browser/ui/webui/settings/ash/kerberos_section.cc
@@ -12,14 +12,14 @@
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
 
-// TODO(https://crbug.com/1164001): remove after migrating to ash.
 namespace mojom {
-using ::ash::settings::mojom::SearchResultDefaultRank;
-using ::ash::settings::mojom::SearchResultIcon;
-using ::ash::settings::mojom::SearchResultType;
+using ::chromeos::settings::mojom::kKerberosAccountsV2SubpagePath;
+using ::chromeos::settings::mojom::kKerberosSectionPath;
+using ::chromeos::settings::mojom::Section;
+using ::chromeos::settings::mojom::Setting;
+using ::chromeos::settings::mojom::Subpage;
 }  // namespace mojom
 
 namespace {
@@ -174,5 +174,4 @@
   }
 }
 
-}  // namespace settings
-}  // namespace chromeos
+}  // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/ash/kerberos_section.h b/chrome/browser/ui/webui/settings/ash/kerberos_section.h
index 2379919..69162c6 100644
--- a/chrome/browser/ui/webui/settings/ash/kerberos_section.h
+++ b/chrome/browser/ui/webui/settings/ash/kerberos_section.h
@@ -8,8 +8,6 @@
 #include "base/values.h"
 #include "chrome/browser/ash/kerberos/kerberos_credentials_manager.h"
 #include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
-// TODO(https://crbug.com/1164001): move to forward declaration
-#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h"
 
 class Profile;
 
@@ -17,8 +15,9 @@
 class WebUIDataSource;
 }  // namespace content
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
+
+class SearchTagRegistry;
 
 // Provides UI strings and search tags for Kerberos settings. Search tags are
 // only added if the feature is enabled by policy.
@@ -35,10 +34,11 @@
   void AddLoadTimeData(content::WebUIDataSource* html_source) override;
   void AddHandlers(content::WebUI* web_ui) override;
   int GetSectionNameMessageId() const override;
-  mojom::Section GetSection() const override;
-  ash::settings::mojom::SearchResultIcon GetSectionIcon() const override;
+  chromeos::settings::mojom::Section GetSection() const override;
+  mojom::SearchResultIcon GetSectionIcon() const override;
   std::string GetSectionPath() const override;
-  bool LogMetric(mojom::Setting setting, base::Value& value) const override;
+  bool LogMetric(chromeos::settings::mojom::Setting setting,
+                 base::Value& value) const override;
   void RegisterHierarchy(HierarchyGenerator* generator) const override;
 
   // KerberosCredentialsManager::Observer:
@@ -50,12 +50,6 @@
   KerberosCredentialsManager* kerberos_credentials_manager_;
 };
 
-}  // namespace settings
-}  // namespace chromeos
-
-// TODO(https://crbug.com/1164001): remove when it moved to ash.
-namespace ash::settings {
-using ::chromeos::settings::KerberosSection;
-}
+}  // namespace ash::settings
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_KERBEROS_SECTION_H_
diff --git a/chrome/browser/ui/webui/settings/ash/languages_section.cc b/chrome/browser/ui/webui/settings/ash/languages_section.cc
index 54097863..8fb8d807 100644
--- a/chrome/browser/ui/webui/settings/ash/languages_section.cc
+++ b/chrome/browser/ui/webui/settings/ash/languages_section.cc
@@ -26,14 +26,19 @@
 #include "ui/base/webui/web_ui_util.h"
 #include "url/gurl.h"
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
 
-// TODO(https://crbug.com/1164001): remove after migrating to ash.
 namespace mojom {
-using ::ash::settings::mojom::SearchResultDefaultRank;
-using ::ash::settings::mojom::SearchResultIcon;
-using ::ash::settings::mojom::SearchResultType;
+using ::chromeos::settings::mojom::kEditDictionarySubpagePath;
+using ::chromeos::settings::mojom::kInputMethodOptionsSubpagePath;
+using ::chromeos::settings::mojom::kInputSubpagePath;
+using ::chromeos::settings::mojom::kJapaneseManageUserDictionarySubpagePath;
+using ::chromeos::settings::mojom::kLanguagesAndInputSectionPath;
+using ::chromeos::settings::mojom::kLanguagesSubpagePath;
+using ::chromeos::settings::mojom::kSmartInputsSubpagePath;
+using ::chromeos::settings::mojom::Section;
+using ::chromeos::settings::mojom::Setting;
+using ::chromeos::settings::mojom::Subpage;
 }  // namespace mojom
 
 namespace {
@@ -150,12 +155,11 @@
 
 bool IsAssistivePersonalInfoAllowed() {
   return !features::IsGuestModeActive() &&
-         base::FeatureList::IsEnabled(
-             ::chromeos::features::kAssistPersonalInfo);
+         base::FeatureList::IsEnabled(ash::features::kAssistPersonalInfo);
 }
 
 bool IsPredictiveWritingAllowed() {
-  return chromeos::features::IsAssistiveMultiWordEnabled();
+  return ash::features::IsAssistiveMultiWordEnabled();
 }
 
 // TODO(crbug/1113611): As Smart Inputs page is renamed to Suggestions.
@@ -353,7 +357,7 @@
   html_source->AddBoolean(
       "allowDiacriticsOnPhysicalKeyboardLongpress",
       base::FeatureList::IsEnabled(
-          ::chromeos::features::kDiacriticsOnPhysicalKeyboardLongpress));
+          ash::features::kDiacriticsOnPhysicalKeyboardLongpress));
 }
 
 void AddLanguagesPageStringsV2(content::WebUIDataSource* html_source) {
@@ -552,15 +556,15 @@
   AddInputPageStringsV2(html_source);
 
   html_source->AddBoolean("enableLanguageSettingsV2Update2", true);
-  html_source->AddBoolean("onDeviceGrammarCheckEnabled",
-                          base::FeatureList::IsEnabled(
-                              ::chromeos::features::kOnDeviceGrammarCheck));
+  html_source->AddBoolean(
+      "onDeviceGrammarCheckEnabled",
+      base::FeatureList::IsEnabled(ash::features::kOnDeviceGrammarCheck));
   html_source->AddBoolean("languagePacksHandwritingEnabled",
-                          ::chromeos::features::IsLanguagePacksEnabled());
+                          ash::features::IsLanguagePacksEnabled());
   html_source->AddBoolean(
       "languageSettingsUpdateJapanese",
       ::base::FeatureList::IsEnabled(
-          ::chromeos::features::kCrosLanguageSettingsUpdateJapanese));
+          ash::features::kCrosLanguageSettingsUpdateJapanese));
 }
 
 void LanguagesSection::AddHandlers(content::WebUI* web_ui) {
@@ -655,8 +659,7 @@
 }
 
 bool LanguagesSection::IsEmojiSuggestionAllowed() const {
-  return pref_service_->GetBoolean(
-      ::chromeos::prefs::kEmojiSuggestionEnterpriseAllowed);
+  return pref_service_->GetBoolean(prefs::kEmojiSuggestionEnterpriseAllowed);
 }
 
 bool LanguagesSection::IsSpellCheckEnabled() const {
@@ -671,5 +674,4 @@
   }
 }
 
-}  // namespace settings
-}  // namespace chromeos
+}  // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/ash/languages_section.h b/chrome/browser/ui/webui/settings/ash/languages_section.h
index 3e4ec2b..a4a23f8d2 100644
--- a/chrome/browser/ui/webui/settings/ash/languages_section.h
+++ b/chrome/browser/ui/webui/settings/ash/languages_section.h
@@ -7,16 +7,15 @@
 
 #include "base/values.h"
 #include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
-// TODO(https://crbug.com/1164001): move to forward declaration
-#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h"
 #include "components/prefs/pref_change_registrar.h"
 
 namespace content {
 class WebUIDataSource;
 }  // namespace content
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
+
+class SearchTagRegistry;
 
 // Provides UI strings and search tags for Languages & Input settings. Search
 // tags for some input features (e.g., Smart Inputs) are used only when
@@ -33,10 +32,11 @@
   void AddLoadTimeData(content::WebUIDataSource* html_source) override;
   void AddHandlers(content::WebUI* web_ui) override;
   int GetSectionNameMessageId() const override;
-  mojom::Section GetSection() const override;
-  ash::settings::mojom::SearchResultIcon GetSectionIcon() const override;
+  chromeos::settings::mojom::Section GetSection() const override;
+  mojom::SearchResultIcon GetSectionIcon() const override;
   std::string GetSectionPath() const override;
-  bool LogMetric(mojom::Setting setting, base::Value& value) const override;
+  bool LogMetric(chromeos::settings::mojom::Setting setting,
+                 base::Value& value) const override;
   void RegisterHierarchy(HierarchyGenerator* generator) const override;
 
   bool IsEmojiSuggestionAllowed() const;
@@ -47,12 +47,6 @@
   PrefChangeRegistrar pref_change_registrar_;
 };
 
-}  // namespace settings
-}  // namespace chromeos
-
-// TODO(https://crbug.com/1164001): remove when it moved to ash.
-namespace ash::settings {
-using ::chromeos::settings::LanguagesSection;
-}
+}  // namespace ash::settings
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_LANGUAGES_SECTION_H_
diff --git a/chrome/browser/ui/webui/settings/ash/main_section.cc b/chrome/browser/ui/webui/settings/ash/main_section.cc
index 22235205..bf76aadd 100644
--- a/chrome/browser/ui/webui/settings/ash/main_section.cc
+++ b/chrome/browser/ui/webui/settings/ash/main_section.cc
@@ -39,13 +39,12 @@
 #include "ui/base/webui/web_ui_util.h"
 #include "ui/chromeos/devicetype_utils.h"
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
 
-// TODO(https://crbug.com/1164001): remove after migrating to ash.
 namespace mojom {
-using ::ash::settings::mojom::SearchResultIcon;
-}
+using ::chromeos::settings::mojom::Section;
+using ::chromeos::settings::mojom::Setting;
+}  // namespace mojom
 
 namespace {
 
@@ -60,9 +59,8 @@
   html_source->AddLocalizedStrings(kLocalizedStrings);
 
   // Used to link to personalization app search results.
-  html_source->AddString(
-      "personalizationAppUrl",
-      ash::personalization_app::kChromeUIPersonalizationAppURL);
+  html_source->AddString("personalizationAppUrl",
+                         personalization_app::kChromeUIPersonalizationAppURL);
 }
 
 void AddUpdateRequiredEolStrings(content::WebUIDataSource* html_source) {
@@ -185,10 +183,10 @@
   // to Personalization Hub though Settings search.
   html_source->AddInteger(
       "settingsSearchEntryPoint",
-      static_cast<int>(ash::PersonalizationEntryPoint::kSettingsSearch));
+      static_cast<int>(PersonalizationEntryPoint::kSettingsSearch));
   html_source->AddInteger(
       "entryPointEnumSize",
-      static_cast<int>(ash::PersonalizationEntryPoint::kMaxValue) + 1);
+      static_cast<int>(PersonalizationEntryPoint::kMaxValue) + 1);
 
   AddSearchInSettingsStrings(html_source);
   AddChromeOSUserStrings(html_source);
@@ -288,5 +286,4 @@
   return plural_string_handler;
 }
 
-}  // namespace settings
-}  // namespace chromeos
+}  // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/ash/main_section.h b/chrome/browser/ui/webui/settings/ash/main_section.h
index f85a3d1..b09037e 100644
--- a/chrome/browser/ui/webui/settings/ash/main_section.h
+++ b/chrome/browser/ui/webui/settings/ash/main_section.h
@@ -14,8 +14,7 @@
 class WebUIDataSource;
 }  // namespace content
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
 
 // Provides UI strings for the main settings page, including the toolbar, search
 // functionality, and common strings. Note that no search tags are provided,
@@ -31,22 +30,17 @@
   void AddLoadTimeData(content::WebUIDataSource* html_source) override;
   void AddHandlers(content::WebUI* web_ui) override;
   int GetSectionNameMessageId() const override;
-  mojom::Section GetSection() const override;
-  ash::settings::mojom::SearchResultIcon GetSectionIcon() const override;
+  chromeos::settings::mojom::Section GetSection() const override;
+  mojom::SearchResultIcon GetSectionIcon() const override;
   std::string GetSectionPath() const override;
-  bool LogMetric(mojom::Setting setting, base::Value& value) const override;
+  bool LogMetric(chromeos::settings::mojom::Setting setting,
+                 base::Value& value) const override;
   void RegisterHierarchy(HierarchyGenerator* generator) const override;
 
   void AddChromeOSUserStrings(content::WebUIDataSource* html_source);
   std::unique_ptr<PluralStringHandler> CreatePluralStringHandler();
 };
 
-}  // namespace settings
-}  // namespace chromeos
-
-// TODO(https://crbug.com/1164001): remove when it moved to ash.
-namespace ash::settings {
-using ::chromeos::settings::MainSection;
-}
+}  // namespace ash::settings
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_MAIN_SECTION_H_
diff --git a/chrome/browser/ui/webui/settings/ash/multidevice_handler.cc b/chrome/browser/ui/webui/settings/ash/multidevice_handler.cc
index bb2537b7..90c409d 100644
--- a/chrome/browser/ui/webui/settings/ash/multidevice_handler.cc
+++ b/chrome/browser/ui/webui/settings/ash/multidevice_handler.cc
@@ -25,7 +25,7 @@
 #include "chrome/browser/nearby_sharing/nearby_sharing_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/ash/session_controller_client_impl.h"
-#include "chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.h"
+#include "chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_dialog.h"
 #include "chromeos/ash/components/multidevice/logging/logging.h"
 #include "chromeos/ash/components/proximity_auth/proximity_auth_pref_names.h"
 #include "components/content_settings/core/common/content_settings_pattern.h"
diff --git a/chrome/browser/ui/webui/settings/ash/multidevice_section.cc b/chrome/browser/ui/webui/settings/ash/multidevice_section.cc
index 99968b4a..17574260 100644
--- a/chrome/browser/ui/webui/settings/ash/multidevice_section.cc
+++ b/chrome/browser/ui/webui/settings/ash/multidevice_section.cc
@@ -39,24 +39,23 @@
 #include "ui/base/webui/web_ui_util.h"
 #include "ui/chromeos/devicetype_utils.h"
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
 
-// TODO(https://crbug.com/1164001): remove after migrating to ash.
 namespace mojom {
-using ::ash::settings::mojom::SearchResultDefaultRank;
-using ::ash::settings::mojom::SearchResultIcon;
-using ::ash::settings::mojom::SearchResultType;
+using ::chromeos::settings::mojom::kMultiDeviceFeaturesSubpagePath;
+using ::chromeos::settings::mojom::kMultiDeviceSectionPath;
+using ::chromeos::settings::mojom::kNearbyShareSubpagePath;
+using ::chromeos::settings::mojom::kSmartLockSubpagePath;
+using ::chromeos::settings::mojom::Section;
+using ::chromeos::settings::mojom::Setting;
+using ::chromeos::settings::mojom::Subpage;
 }  // namespace mojom
 
 namespace {
 
-using Feature = ::ash::multidevice_setup::mojom::Feature;
-using FeatureState = ::ash::multidevice_setup::mojom::FeatureState;
-using HostStatus = ::ash::multidevice_setup::mojom::HostStatus;
-
-// TODO(https://crbug.com/1164001): remove after migrating to namespace ash.
-namespace phonehub = ::ash::phonehub;
+using Feature = multidevice_setup::mojom::Feature;
+using FeatureState = multidevice_setup::mojom::FeatureState;
+using HostStatus = multidevice_setup::mojom::HostStatus;
 
 const std::vector<SearchConcept>& GetMultiDeviceOptedInSearchConcepts() {
   static const base::NoDestructor<std::vector<SearchConcept>> tags(
@@ -324,7 +323,7 @@
     phonehub::PhoneHubManager* phone_hub_manager,
     android_sms::AndroidSmsService* android_sms_service,
     PrefService* pref_service,
-    ash::eche_app::EcheAppManager* eche_app_manager)
+    eche_app::EcheAppManager* eche_app_manager)
     : OsSettingsSection(profile, search_tag_registry),
       multidevice_setup_client_(multidevice_setup_client),
       phone_hub_manager_(phone_hub_manager),
@@ -347,7 +346,7 @@
   if (features::IsEcheSWAEnabled()) {
     pref_change_registrar_.Init(pref_service_);
     pref_change_registrar_.Add(
-        ash::prefs::kEnableAutoScreenLock,
+        prefs::kEnableAutoScreenLock,
         base::BindRepeating(&MultiDeviceSection::OnEnableScreenLockChanged,
                             base::Unretained(this)));
     pref_change_registrar_.Add(
@@ -511,10 +510,9 @@
   };
   html_source->AddLocalizedStrings(kLocalizedStrings);
 
-  html_source->AddBoolean(
-      "multideviceAllowedByPolicy",
-      chromeos::multidevice_setup::AreAnyMultiDeviceFeaturesAllowed(
-          profile()->GetPrefs()));
+  html_source->AddBoolean("multideviceAllowedByPolicy",
+                          multidevice_setup::AreAnyMultiDeviceFeaturesAllowed(
+                              profile()->GetPrefs()));
   html_source->AddString(
       "multideviceNotificationAccessSetupScreenLockTitle",
       ui::SubstituteChromeOSDeviceType(
@@ -889,5 +887,4 @@
   }
 }
 
-}  // namespace settings
-}  // namespace chromeos
+}  // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/ash/multidevice_section.h b/chrome/browser/ui/webui/settings/ash/multidevice_section.h
index 0e1a497..200e9f23 100644
--- a/chrome/browser/ui/webui/settings/ash/multidevice_section.h
+++ b/chrome/browser/ui/webui/settings/ash/multidevice_section.h
@@ -5,17 +5,11 @@
 #ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_MULTIDEVICE_SECTION_H_
 #define CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_MULTIDEVICE_SECTION_H_
 
-// TODO(https://crbug.com/1164001): move to forward declaration.
-#include "ash/components/phonehub/phone_hub_manager.h"
 #include "ash/services/multidevice_setup/public/cpp/multidevice_setup_client.h"
 #include "ash/webui/eche_app_ui/eche_app_manager.h"
 #include "base/values.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
-// TODO(https://crbug.com/1164001): move to forward declaration.
-#include "chrome/browser/ash/android_sms/android_sms_service.h"
 #include "chrome/browser/ui/webui/nearby_share/public/mojom/nearby_share_settings.mojom.h"
-// TODO(https://crbug.com/1164001): move to forward declaration
-#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h"
+#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
 #include "components/prefs/pref_change_registrar.h"
 
 class PrefService;
@@ -24,9 +18,20 @@
 class WebUIDataSource;
 }  // namespace content
 
-namespace chromeos {
+namespace ash {
+
+namespace android_sms {
+class AndroidSmsService;
+}
+
+namespace phonehub {
+class PhoneHubManager;
+}
+
 namespace settings {
 
+class SearchTagRegistry;
+
 // Provides UI strings and search tags for MultiDevice settings. Different
 // search tags are registered depending on whether MultiDevice features are
 // allowed and whether the user has opted into the suite of features.
@@ -42,7 +47,7 @@
       phonehub::PhoneHubManager* phone_hub_manager,
       android_sms::AndroidSmsService* android_sms_service,
       PrefService* pref_service,
-      ash::eche_app::EcheAppManager* eche_app_manager);
+      eche_app::EcheAppManager* eche_app_manager);
   ~MultiDeviceSection() override;
 
  private:
@@ -51,10 +56,11 @@
   void AddLoadTimeData(content::WebUIDataSource* html_source) override;
   void AddHandlers(content::WebUI* web_ui) override;
   int GetSectionNameMessageId() const override;
-  mojom::Section GetSection() const override;
-  ash::settings::mojom::SearchResultIcon GetSectionIcon() const override;
+  chromeos::settings::mojom::Section GetSection() const override;
+  mojom::SearchResultIcon GetSectionIcon() const override;
   std::string GetSectionPath() const override;
-  bool LogMetric(mojom::Setting setting, base::Value& value) const override;
+  bool LogMetric(chromeos::settings::mojom::Setting setting,
+                 base::Value& value) const override;
   void RegisterHierarchy(HierarchyGenerator* generator) const override;
 
   // multidevice_setup::MultiDeviceSetupClient::Observer:
@@ -71,7 +77,7 @@
   // Phone screen lock status pref change observer.
   void OnScreenLockStatusChanged();
 
-  bool IsFeatureSupported(ash::multidevice_setup::mojom::Feature feature);
+  bool IsFeatureSupported(multidevice_setup::mojom::Feature feature);
   void RefreshNearbyBackgroundScanningShareSearchConcepts();
 
   // nearby_share::mojom::NearbyShareSettingsObserver:
@@ -95,16 +101,11 @@
   android_sms::AndroidSmsService* android_sms_service_;
   PrefService* pref_service_;
   PrefChangeRegistrar pref_change_registrar_;
-  ash::eche_app::EcheAppManager* eche_app_manager_;
+  eche_app::EcheAppManager* eche_app_manager_;
   content::WebUIDataSource* html_source_;
 };
 
 }  // namespace settings
-}  // namespace chromeos
-
-// TODO(https://crbug.com/1164001): remove when it moved to ash.
-namespace ash::settings {
-using ::chromeos::settings::MultiDeviceSection;
-}
+}  // namespace ash
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_MULTIDEVICE_SECTION_H_
diff --git a/chrome/browser/ui/webui/settings/ash/multidevice_section_unittest.cc b/chrome/browser/ui/webui/settings/ash/multidevice_section_unittest.cc
index 9859f2e..b87bb0d 100644
--- a/chrome/browser/ui/webui/settings/ash/multidevice_section_unittest.cc
+++ b/chrome/browser/ui/webui/settings/ash/multidevice_section_unittest.cc
@@ -25,8 +25,7 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
 
 class MockWebUIDataSource : public content::WebUIDataSource {
  public:
@@ -87,12 +86,11 @@
   // testing::Test:
   void SetUp() override {
     ASSERT_TRUE(profile_manager_.SetUp());
-    pref_service_.registry()->RegisterBooleanPref(
-        ash::prefs::kEnableAutoScreenLock, false);
+    pref_service_.registry()->RegisterBooleanPref(prefs::kEnableAutoScreenLock,
+                                                  false);
     pref_service_.registry()->RegisterIntegerPref(
-        ash::phonehub::prefs::kScreenLockStatus,
-        static_cast<int>(
-            ash::phonehub::ScreenLockManager::LockStatus::kLockedOn));
+        phonehub::prefs::kScreenLockStatus,
+        static_cast<int>(phonehub::ScreenLockManager::LockStatus::kLockedOn));
     mock_web_ui_data_source_ = std::make_unique<MockWebUIDataSource>();
     service_proxy_ =
         std::make_unique<local_search_service::LocalSearchServiceProxy>(
@@ -109,7 +107,7 @@
         fake_multidevice_setup_client_.get(), fake_phone_hub_manager_.get(),
         android_sms::AndroidSmsServiceFactory::GetForBrowserContext(profile),
         &pref_service_,
-        ash::eche_app::EcheAppManagerFactory::GetForProfile(profile));
+        eche_app::EcheAppManagerFactory::GetForProfile(profile));
   }
 
   void VerifyOnEnableScreenLockChangedIsCalled() {
@@ -121,7 +119,7 @@
         *mock_web_ui_data_source_,
         AddBoolean(testing::Eq("isChromeosScreenLockEnabled"), testing::_))
         .Times(1);
-    pref_service_.SetBoolean(ash::prefs::kEnableAutoScreenLock, true);
+    pref_service_.SetBoolean(prefs::kEnableAutoScreenLock, true);
   }
 
   void VerifyOnScreenLockStatusChangedIsCalled() {
@@ -133,9 +131,8 @@
                 AddBoolean(testing::Eq("isPhoneScreenLockEnabled"), testing::_))
         .Times(1);
     pref_service_.SetInteger(
-        ash::phonehub::prefs::kScreenLockStatus,
-        static_cast<int>(
-            ash::phonehub::ScreenLockManager::LockStatus::kLockedOn));
+        phonehub::prefs::kScreenLockStatus,
+        static_cast<int>(phonehub::ScreenLockManager::LockStatus::kLockedOn));
   }
 
  private:
@@ -160,5 +157,4 @@
   VerifyOnScreenLockStatusChangedIsCalled();
 }
 
-}  // namespace settings
-}  // namespace chromeos
+}  // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/ash/os_settings_section.cc b/chrome/browser/ui/webui/settings/ash/os_settings_section.cc
index bd230e1c..82e085e 100644
--- a/chrome/browser/ui/webui/settings/ash/os_settings_section.cc
+++ b/chrome/browser/ui/webui/settings/ash/os_settings_section.cc
@@ -15,7 +15,6 @@
 namespace ash::settings {
 
 namespace mojom {
-using ::chromeos::settings::mojom::Section;
 using ::chromeos::settings::mojom::Setting;
 using ::chromeos::settings::mojom::Subpage;
 }  // namespace mojom
diff --git a/chrome/browser/ui/webui/settings/ash/os_settings_sections.h b/chrome/browser/ui/webui/settings/ash/os_settings_sections.h
index c2cca4c4..6daaa4b 100644
--- a/chrome/browser/ui/webui/settings/ash/os_settings_sections.h
+++ b/chrome/browser/ui/webui/settings/ash/os_settings_sections.h
@@ -84,4 +84,9 @@
 }  // namespace settings
 }  // namespace ash
 
+// TODO(https://crbug.com/1164001): remove when the migration is finished.
+namespace chromeos::settings {
+using ::ash::settings::OsSettingsSections;
+}
+
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_OS_SETTINGS_SECTIONS_H_
diff --git a/chrome/browser/ui/webui/settings/ash/people_section.cc b/chrome/browser/ui/webui/settings/ash/people_section.cc
index 41340e9..178cd794 100644
--- a/chrome/browser/ui/webui/settings/ash/people_section.cc
+++ b/chrome/browser/ui/webui/settings/ash/people_section.cc
@@ -62,20 +62,21 @@
 #include "ui/chromeos/devicetype_utils.h"
 #include "ui/chromeos/resources/grit/ui_chromeos_resources.h"
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
 
-// TODO(https://crbug.com/1164001): remove after migrating to ash.
 namespace mojom {
-using ::ash::settings::mojom::SearchResultDefaultRank;
-using ::ash::settings::mojom::SearchResultIcon;
-using ::ash::settings::mojom::SearchResultType;
+using ::chromeos::settings::mojom::kMyAccountsSubpagePath;
+using ::chromeos::settings::mojom::kPeopleSectionPath;
+using ::chromeos::settings::mojom::kSyncDeprecatedAdvancedSubpagePath;
+using ::chromeos::settings::mojom::kSyncSetupSubpagePath;
+using ::chromeos::settings::mojom::kSyncSubpagePath;
+using ::chromeos::settings::mojom::Section;
+using ::chromeos::settings::mojom::Setting;
+using ::chromeos::settings::mojom::Subpage;
 }  // namespace mojom
 
 namespace {
 
-using ::ash::IsAccountManagerAvailable;
-
 const std::vector<SearchConcept>& GetPeopleSearchConcepts() {
   static const base::NoDestructor<std::vector<SearchConcept>> tags({
       {IDS_OS_SETTINGS_TAG_PEOPLE_ACCOUNTS,
@@ -192,7 +193,7 @@
   };
   html_source->AddLocalizedStrings(kLocalizedStrings);
 
-  if (ash::AccountAppsAvailability::IsArcAccountRestrictionsEnabled()) {
+  if (AccountAppsAvailability::IsArcAccountRestrictionsEnabled()) {
     html_source->AddString("accountListDescription",
                            l10n_util::GetStringFUTF16(
                                IDS_SETTINGS_ACCOUNT_MANAGER_LIST_DESCRIPTION_V2,
@@ -227,7 +228,7 @@
                           crosapi::browser_util::IsLacrosEnabled());
   html_source->AddBoolean(
       "arcAccountRestrictionsEnabled",
-      ash::AccountAppsAvailability::IsArcAccountRestrictionsEnabled());
+      AccountAppsAvailability::IsArcAccountRestrictionsEnabled());
 }
 
 void AddLockScreenPageStrings(content::WebUIDataSource* html_source,
@@ -285,7 +286,7 @@
 
   html_source->AddBoolean("quickUnlockEnabled", quick_unlock::IsPinEnabled());
   html_source->AddBoolean("quickUnlockPinAutosubmitFeatureEnabled",
-                          chromeos::features::IsPinAutosubmitFeatureEnabled());
+                          ash::features::IsPinAutosubmitFeatureEnabled());
   html_source->AddBoolean("quickUnlockDisabledByPolicy",
                           quick_unlock::IsPinDisabledByPolicy(
                               pref_service, quick_unlock::Purpose::kAny));
@@ -561,7 +562,7 @@
     DCHECK(account_manager_facade_);
     account_manager_facade_observation_.Observe(account_manager_facade_);
     account_apps_availability_ =
-        ash::AccountAppsAvailabilityFactory::GetForProfile(profile);
+        AccountAppsAvailabilityFactory::GetForProfile(profile);
     FetchAccounts();
   }
 
@@ -809,5 +810,4 @@
                                             quick_unlock::Purpose::kAny);
 }
 
-}  // namespace settings
-}  // namespace chromeos
+}  // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/ash/people_section.h b/chrome/browser/ui/webui/settings/ash/people_section.h
index 44b00727..7e54b36 100644
--- a/chrome/browser/ui/webui/settings/ash/people_section.h
+++ b/chrome/browser/ui/webui/settings/ash/people_section.h
@@ -9,8 +9,6 @@
 #include "base/scoped_observation.h"
 #include "base/values.h"
 #include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
-// TODO(https://crbug.com/1164001): move to forward declaration
-#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h"
 #include "components/account_manager_core/account.h"
 #include "components/account_manager_core/account_manager_facade.h"
 #include "components/account_manager_core/chromeos/account_manager.h"
@@ -34,13 +32,13 @@
 }  // namespace syncer
 
 namespace ash {
-class AccountAppsAvailability;
-}
 
-namespace chromeos {
+class AccountAppsAvailability;
 
 namespace settings {
 
+class SearchTagRegistry;
+
 // Provides UI strings and search tags for People settings. Search tags are only
 // added for non-guest sessions.
 //
@@ -63,10 +61,11 @@
   void AddLoadTimeData(content::WebUIDataSource* html_source) override;
   void AddHandlers(content::WebUI* web_ui) override;
   int GetSectionNameMessageId() const override;
-  mojom::Section GetSection() const override;
-  ash::settings::mojom::SearchResultIcon GetSectionIcon() const override;
+  chromeos::settings::mojom::Section GetSection() const override;
+  mojom::SearchResultIcon GetSectionIcon() const override;
   std::string GetSectionPath() const override;
-  bool LogMetric(mojom::Setting setting, base::Value& value) const override;
+  bool LogMetric(chromeos::settings::mojom::Setting setting,
+                 base::Value& value) const override;
   void RegisterHierarchy(HierarchyGenerator* generator) const override;
 
   // AccountManagerFacade::Observer:
@@ -82,7 +81,7 @@
 
   account_manager::AccountManager* account_manager_ = nullptr;
   account_manager::AccountManagerFacade* account_manager_facade_ = nullptr;
-  ash::AccountAppsAvailability* account_apps_availability_ = nullptr;
+  AccountAppsAvailability* account_apps_availability_ = nullptr;
   SupervisedUserService* supervised_user_service_;
   signin::IdentityManager* identity_manager_;
   PrefService* pref_service_;
@@ -97,11 +96,6 @@
 };
 
 }  // namespace settings
-}  // namespace chromeos
-
-// TODO(https://crbug.com/1164001): remove when it moved to ash.
-namespace ash::settings {
-using ::chromeos::settings::PeopleSection;
-}
+}  // namespace ash
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_PEOPLE_SECTION_H_
diff --git a/chrome/browser/ui/webui/settings/ash/personalization_section.cc b/chrome/browser/ui/webui/settings/ash/personalization_section.cc
index 31222dc..20f57f1 100644
--- a/chrome/browser/ui/webui/settings/ash/personalization_section.cc
+++ b/chrome/browser/ui/webui/settings/ash/personalization_section.cc
@@ -12,12 +12,13 @@
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
 
-namespace chromeos::settings {
+namespace ash::settings {
 
-// TODO(https://crbug.com/1164001): remove after migrating to ash.
 namespace mojom {
-using ::ash::settings::mojom::SearchResultIcon;
-}
+using ::chromeos::settings::mojom::kPersonalizationSectionPath;
+using ::chromeos::settings::mojom::Section;
+using ::chromeos::settings::mojom::Setting;
+}  // namespace mojom
 
 PersonalizationSection::PersonalizationSection(
     Profile* profile,
@@ -69,4 +70,4 @@
   generator->RegisterTopLevelSetting(mojom::Setting::kOpenWallpaper);
 }
 
-}  // namespace chromeos::settings
+}  // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/ash/personalization_section.h b/chrome/browser/ui/webui/settings/ash/personalization_section.h
index cff0cd3..a004993 100644
--- a/chrome/browser/ui/webui/settings/ash/personalization_section.h
+++ b/chrome/browser/ui/webui/settings/ash/personalization_section.h
@@ -7,8 +7,6 @@
 
 #include "base/values.h"
 #include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
-// TODO(https://crbug.com/1164001): move to forward declaration
-#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h"
 #include "components/prefs/pref_change_registrar.h"
 
 class PrefService;
@@ -17,8 +15,9 @@
 class WebUIDataSource;
 }  // namespace content
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
+
+class SearchTagRegistry;
 
 // Provides UI strings and search tags for Personalization settings. Search tags
 // are only added when not in guest mode, and Ambient mode settings are added
@@ -35,21 +34,16 @@
   void AddLoadTimeData(content::WebUIDataSource* html_source) override;
   void AddHandlers(content::WebUI* web_ui) override;
   int GetSectionNameMessageId() const override;
-  mojom::Section GetSection() const override;
-  ash::settings::mojom::SearchResultIcon GetSectionIcon() const override;
+  chromeos::settings::mojom::Section GetSection() const override;
+  mojom::SearchResultIcon GetSectionIcon() const override;
   std::string GetSectionPath() const override;
-  bool LogMetric(mojom::Setting setting, base::Value& value) const override;
+  bool LogMetric(chromeos::settings::mojom::Setting setting,
+                 base::Value& value) const override;
   void RegisterHierarchy(HierarchyGenerator* generator) const override;
 
   PrefChangeRegistrar pref_change_registrar_;
 };
 
-}  // namespace settings
-}  // namespace chromeos
-
-// TODO(https://crbug.com/1164001): remove when it moved to ash.
-namespace ash::settings {
-using ::chromeos::settings::PersonalizationSection;
-}
+}  // namespace ash::settings
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_PERSONALIZATION_SECTION_H_
diff --git a/chrome/browser/ui/webui/settings/ash/pref_names.cc b/chrome/browser/ui/webui/settings/ash/pref_names.cc
index 2356d615b..e205cf7f 100644
--- a/chrome/browser/ui/webui/settings/ash/pref_names.cc
+++ b/chrome/browser/ui/webui/settings/ash/pref_names.cc
@@ -4,9 +4,7 @@
 
 #include "chrome/browser/ui/webui/settings/ash/pref_names.h"
 
-namespace chromeos {
-namespace settings {
-namespace prefs {
+namespace ash::settings::prefs {
 
 // Boolean specifying whether OS wallpaper sync is enabled. This is stored
 // separately from the other OS sync preferences because it's an edge case;
@@ -19,6 +17,4 @@
 // TODO(https://crbug.com/1318106): Create a helper method that checks both.
 const char kSyncOsWallpaper[] = "sync.os_wallpaper";
 
-}  // namespace prefs
-}  // namespace settings
-}  // namespace chromeos
+}  // namespace ash::settings::prefs
diff --git a/chrome/browser/ui/webui/settings/ash/pref_names.h b/chrome/browser/ui/webui/settings/ash/pref_names.h
index a9e7b5ab..18c1f8a 100644
--- a/chrome/browser/ui/webui/settings/ash/pref_names.h
+++ b/chrome/browser/ui/webui/settings/ash/pref_names.h
@@ -5,19 +5,15 @@
 #ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_PREF_NAMES_H_
 #define CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_PREF_NAMES_H_
 
-namespace chromeos {
-namespace settings {
-namespace prefs {
+namespace ash::settings::prefs {
 
 extern const char kSyncOsWallpaper[];
 
-}  // namespace prefs
-}  // namespace settings
-}  // namespace chromeos
+}  // namespace ash::settings::prefs
 
-// TODO(https://crbug.com/1164001): remove when it moved to ash.
-namespace ash::settings::prefs {
-using ::chromeos::settings::prefs::kSyncOsWallpaper;
+// TODO(https://crbug.com/1164001): remove when the migration is finished.
+namespace chromeos::settings::prefs {
+using ::ash::settings::prefs::kSyncOsWallpaper;
 }
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_PREF_NAMES_H_
diff --git a/chrome/browser/ui/webui/settings/ash/printing_section.cc b/chrome/browser/ui/webui/settings/ash/printing_section.cc
index 263c371..8e67d1f1 100644
--- a/chrome/browser/ui/webui/settings/ash/printing_section.cc
+++ b/chrome/browser/ui/webui/settings/ash/printing_section.cc
@@ -7,6 +7,7 @@
 #include "base/no_destructor.h"
 #include "chrome/browser/ui/webui/settings/ash/cups_printers_handler.h"
 #include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h"
+#include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom-forward.h"
 #include "chrome/browser/ui/webui/webui_util.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/url_constants.h"
@@ -16,14 +17,14 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/webui/web_ui_util.h"
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
 
-// TODO(https://crbug.com/1164001): remove after migrating to ash.
 namespace mojom {
-using ::ash::settings::mojom::SearchResultDefaultRank;
-using ::ash::settings::mojom::SearchResultIcon;
-using ::ash::settings::mojom::SearchResultType;
+using ::chromeos::settings::mojom::kPrintingDetailsSubpagePath;
+using ::chromeos::settings::mojom::kPrintingSectionPath;
+using ::chromeos::settings::mojom::Section;
+using ::chromeos::settings::mojom::Setting;
+using ::chromeos::settings::mojom::Subpage;
 }  // namespace mojom
 
 namespace {
@@ -323,8 +324,9 @@
                             kPrintingDetailsSettings, generator);
 }
 
-void PrintingSection::OnPrintersChanged(PrinterClass printer_class,
-                                        const std::vector<Printer>& printers) {
+void PrintingSection::OnPrintersChanged(
+    chromeos::PrinterClass printer_class,
+    const std::vector<chromeos::Printer>& printers) {
   UpdateSavedPrintersSearchTags();
 }
 
@@ -333,12 +335,11 @@
   SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
   updater.RemoveSearchTags(GetSavedPrintersSearchConcepts());
 
-  std::vector<Printer> saved_printers =
-      printers_manager_->GetPrinters(PrinterClass::kSaved);
+  std::vector<chromeos::Printer> saved_printers =
+      printers_manager_->GetPrinters(chromeos::PrinterClass::kSaved);
   if (!saved_printers.empty()) {
     updater.AddSearchTags(GetSavedPrintersSearchConcepts());
   }
 }
 
-}  // namespace settings
-}  // namespace chromeos
+}  // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/ash/printing_section.h b/chrome/browser/ui/webui/settings/ash/printing_section.h
index 3a391595..95b7ddd1 100644
--- a/chrome/browser/ui/webui/settings/ash/printing_section.h
+++ b/chrome/browser/ui/webui/settings/ash/printing_section.h
@@ -8,15 +8,14 @@
 #include "base/values.h"
 #include "chrome/browser/ash/printing/cups_printers_manager.h"
 #include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
-// TODO(https://crbug.com/1164001): move to forward declaration
-#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h"
 
 namespace content {
 class WebUIDataSource;
 }  // namespace content
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
+
+class SearchTagRegistry;
 
 // Provides UI strings and search tags for Printing settings.
 class PrintingSection : public OsSettingsSection,
@@ -32,27 +31,23 @@
   void AddLoadTimeData(content::WebUIDataSource* html_source) override;
   void AddHandlers(content::WebUI* web_ui) override;
   int GetSectionNameMessageId() const override;
-  mojom::Section GetSection() const override;
-  ash::settings::mojom::SearchResultIcon GetSectionIcon() const override;
+  chromeos::settings::mojom::Section GetSection() const override;
+  mojom::SearchResultIcon GetSectionIcon() const override;
   std::string GetSectionPath() const override;
-  bool LogMetric(mojom::Setting setting, base::Value& value) const override;
+  bool LogMetric(chromeos::settings::mojom::Setting setting,
+                 base::Value& value) const override;
   void RegisterHierarchy(HierarchyGenerator* generator) const override;
 
   // CupsPrintersManager::Observer
-  void OnPrintersChanged(PrinterClass printer_class,
-                         const std::vector<Printer>& printers) override;
+  void OnPrintersChanged(
+      chromeos::PrinterClass printer_class,
+      const std::vector<chromeos::Printer>& printers) override;
 
   void UpdateSavedPrintersSearchTags();
 
   CupsPrintersManager* printers_manager_;
 };
 
-}  // namespace settings
-}  // namespace chromeos
-
-// TODO(https://crbug.com/1164001): remove when it moved to ash.
-namespace ash::settings {
-using ::chromeos::settings::PrintingSection;
-}
+}  // namespace ash::settings
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_PRINTING_SECTION_H_
diff --git a/chrome/browser/ui/webui/settings/ash/privacy_section.cc b/chrome/browser/ui/webui/settings/ash/privacy_section.cc
index 8c675f1..6b94d06 100644
--- a/chrome/browser/ui/webui/settings/ash/privacy_section.cc
+++ b/chrome/browser/ui/webui/settings/ash/privacy_section.cc
@@ -33,14 +33,18 @@
 #include "ui/base/webui/web_ui_util.h"
 #include "ui/chromeos/devicetype_utils.h"
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
 
-// TODO(https://crbug.com/1164001): remove after migrating to ash.
 namespace mojom {
-using ::ash::settings::mojom::SearchResultDefaultRank;
-using ::ash::settings::mojom::SearchResultIcon;
-using ::ash::settings::mojom::SearchResultType;
+using ::chromeos::settings::mojom::kFingerprintSubpagePathV2;
+using ::chromeos::settings::mojom::kManageOtherPeopleSubpagePathV2;
+using ::chromeos::settings::mojom::kPrivacyAndSecuritySectionPath;
+using ::chromeos::settings::mojom::kPrivacyHubSubpagePath;
+using ::chromeos::settings::mojom::kSecurityAndSignInSubpagePathV2;
+using ::chromeos::settings::mojom::kSmartPrivacySubpagePath;
+using ::chromeos::settings::mojom::Section;
+using ::chromeos::settings::mojom::Setting;
+using ::chromeos::settings::mojom::Subpage;
 }  // namespace mojom
 
 namespace {
@@ -240,7 +244,7 @@
 bool IsSecureDnsAvailable() {
   return
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-      base::FeatureList::IsEnabled(chromeos::features::kEnableDnsProxy) &&
+      base::FeatureList::IsEnabled(ash::features::kEnableDnsProxy) &&
       base::FeatureList::IsEnabled(::features::kDnsProxyEnableDOH) &&
 #endif
       ::features::kDnsOverHttpsShowUiParam.Get();
@@ -324,6 +328,12 @@
        IDS_OS_SETTINGS_SMART_PRIVACY_QUICK_DIM_TITLE},
       {"smartPrivacyQuickDimSubtext",
        IDS_OS_SETTINGS_SMART_PRIVACY_QUICK_DIM_SUBTEXT},
+      {"smartPrivacyQuickLockLong",
+       IDS_OS_SETTINGS_SMART_PRIVACY_QUICK_LOCK_LONG},
+      {"smartPrivacyQuickLockShort",
+       IDS_OS_SETTINGS_SMART_PRIVACY_QUICK_LOCK_SHORT},
+      {"smartPrivacyQuickLockTitle",
+       IDS_OS_SETTINGS_SMART_PRIVACY_QUICK_LOCK_TITLE},
       {"smartPrivacySnoopingTitle",
        IDS_OS_SETTINGS_SMART_PRIVACY_SNOOPING_TITLE},
       {"smartPrivacySnoopingSubtext",
@@ -515,5 +525,4 @@
   }
 }
 
-}  // namespace settings
-}  // namespace chromeos
+}  // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/ash/privacy_section.h b/chrome/browser/ui/webui/settings/ash/privacy_section.h
index 62e8b3f..be08a76 100644
--- a/chrome/browser/ui/webui/settings/ash/privacy_section.h
+++ b/chrome/browser/ui/webui/settings/ash/privacy_section.h
@@ -7,8 +7,6 @@
 
 #include "base/values.h"
 #include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
-// TODO(https://crbug.com/1164001): move to forward declaration
-#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h"
 #include "components/prefs/pref_change_registrar.h"
 
 class PrefService;
@@ -17,8 +15,9 @@
 class WebUIDataSource;
 }  // namespace content
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
+
+class SearchTagRegistry;
 
 // Provides UI strings and search tags for Privacy settings. Note that some
 // search tags are added only for official Google Chrome OS builds.
@@ -34,10 +33,11 @@
   void AddHandlers(content::WebUI* web_ui) override;
   void AddLoadTimeData(content::WebUIDataSource* html_source) override;
   int GetSectionNameMessageId() const override;
-  mojom::Section GetSection() const override;
-  ash::settings::mojom::SearchResultIcon GetSectionIcon() const override;
+  chromeos::settings::mojom::Section GetSection() const override;
+  mojom::SearchResultIcon GetSectionIcon() const override;
   std::string GetSectionPath() const override;
-  bool LogMetric(mojom::Setting setting, base::Value& value) const override;
+  bool LogMetric(chromeos::settings::mojom::Setting setting,
+                 base::Value& value) const override;
   void RegisterHierarchy(HierarchyGenerator* generator) const override;
 
   bool AreFingerprintSettingsAllowed();
@@ -47,12 +47,6 @@
   PrefChangeRegistrar fingerprint_pref_change_registrar_;
 };
 
-}  // namespace settings
-}  // namespace chromeos
-
-// TODO(https://crbug.com/1164001): remove when it moved to ash.
-namespace ash::settings {
-using ::chromeos::settings::PrivacySection;
-}
+}  // namespace ash::settings
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_PRIVACY_SECTION_H_
diff --git a/chrome/browser/ui/webui/settings/ash/reset_section.cc b/chrome/browser/ui/webui/settings/ash/reset_section.cc
index 6630a8b6..d390b1b 100644
--- a/chrome/browser/ui/webui/settings/ash/reset_section.cc
+++ b/chrome/browser/ui/webui/settings/ash/reset_section.cc
@@ -17,14 +17,13 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/webui/web_ui_util.h"
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
 
-// TODO(https://crbug.com/1164001): remove after migrating to ash.
 namespace mojom {
-using ::ash::settings::mojom::SearchResultDefaultRank;
-using ::ash::settings::mojom::SearchResultIcon;
-using ::ash::settings::mojom::SearchResultType;
+using ::chromeos::settings::mojom::kResetSectionPath;
+using ::chromeos::settings::mojom::Section;
+using ::chromeos::settings::mojom::Setting;
+using ::chromeos::settings::mojom::Subpage;
 }  // namespace mojom
 
 namespace {
@@ -133,5 +132,4 @@
   generator->RegisterTopLevelSetting(mojom::Setting::kPowerwash);
 }
 
-}  // namespace settings
-}  // namespace chromeos
+}  // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/ash/reset_section.h b/chrome/browser/ui/webui/settings/ash/reset_section.h
index 9c914d29..6fbc041 100644
--- a/chrome/browser/ui/webui/settings/ash/reset_section.h
+++ b/chrome/browser/ui/webui/settings/ash/reset_section.h
@@ -7,15 +7,14 @@
 
 #include "base/values.h"
 #include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
-// TODO(https://crbug.com/1164001): move to forward declaration
-#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h"
 
 namespace content {
 class WebUIDataSource;
 }  // namespace content
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
+
+class SearchTagRegistry;
 
 // Provides UI strings and search tags for Reset settings. Note that search tags
 // are only added when powerwashing is allowed, since currently this is the only
@@ -30,19 +29,14 @@
   void AddLoadTimeData(content::WebUIDataSource* html_source) override;
   void AddHandlers(content::WebUI* web_ui) override;
   int GetSectionNameMessageId() const override;
-  mojom::Section GetSection() const override;
-  ash::settings::mojom::SearchResultIcon GetSectionIcon() const override;
+  chromeos::settings::mojom::Section GetSection() const override;
+  mojom::SearchResultIcon GetSectionIcon() const override;
   std::string GetSectionPath() const override;
-  bool LogMetric(mojom::Setting setting, base::Value& value) const override;
+  bool LogMetric(chromeos::settings::mojom::Setting setting,
+                 base::Value& value) const override;
   void RegisterHierarchy(HierarchyGenerator* generator) const override;
 };
 
-}  // namespace settings
-}  // namespace chromeos
-
-// TODO(https://crbug.com/1164001): remove when it moved to ash.
-namespace ash::settings {
-using ::chromeos::settings::ResetSection;
-}
+}  // namespace ash::settings
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_RESET_SECTION_H_
diff --git a/chrome/browser/ui/webui/settings/ash/search/search_handler.h b/chrome/browser/ui/webui/settings/ash/search/search_handler.h
index 80e6370..5e978f82 100644
--- a/chrome/browser/ui/webui/settings/ash/search/search_handler.h
+++ b/chrome/browser/ui/webui/settings/ash/search/search_handler.h
@@ -8,10 +8,6 @@
 #include <vector>
 
 #include "base/gtest_prod_util.h"
-// TODO(https://crbug.com/1164001): move to forward declaration
-#include "chrome/browser/ui/webui/settings/ash/hierarchy.h"
-// TODO(https://crbug.com/1164001): move to forward declaration
-#include "chrome/browser/ui/webui/settings/ash/os_settings_sections.h"
 #include "chrome/browser/ui/webui/settings/ash/search/search.mojom.h"
 #include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h"
 #include "chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy.h"
@@ -25,6 +21,8 @@
 
 namespace ash::settings {
 
+class Hierarchy;
+class OsSettingsSections;
 struct SearchConcept;
 
 // Handles search queries for Chrome OS settings. Search() is expected to be
diff --git a/chrome/browser/ui/webui/settings/ash/search_section.cc b/chrome/browser/ui/webui/settings/ash/search_section.cc
index 635731e1..935e72a8 100644
--- a/chrome/browser/ui/webui/settings/ash/search_section.cc
+++ b/chrome/browser/ui/webui/settings/ash/search_section.cc
@@ -32,14 +32,15 @@
 #include "ui/base/webui/web_ui_util.h"
 #include "ui/chromeos/devicetype_utils.h"
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
 
-// TODO(https://crbug.com/1164001): remove after migrating to ash.
 namespace mojom {
-using ::ash::settings::mojom::SearchResultDefaultRank;
-using ::ash::settings::mojom::SearchResultIcon;
-using ::ash::settings::mojom::SearchResultType;
+using ::chromeos::settings::mojom::kAssistantSubpagePath;
+using ::chromeos::settings::mojom::kSearchAndAssistantSectionPath;
+using ::chromeos::settings::mojom::kSearchSubpagePath;
+using ::chromeos::settings::mojom::Section;
+using ::chromeos::settings::mojom::Setting;
+using ::chromeos::settings::mojom::Subpage;
 }  // namespace mojom
 
 namespace {
@@ -269,7 +270,7 @@
   SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
   updater.AddSearchTags(GetSearchPageSearchConcepts());
 
-  ash::AssistantState* assistant_state = ash::AssistantState::Get();
+  AssistantState* assistant_state = AssistantState::Get();
   if (IsAssistantAllowed() && assistant_state) {
     updater.AddSearchTags(GetAssistantSearchConcepts());
 
@@ -284,7 +285,7 @@
 }
 
 SearchSection::~SearchSection() {
-  ash::AssistantState* assistant_state = ash::AssistantState::Get();
+  AssistantState* assistant_state = AssistantState::Get();
   if (IsAssistantAllowed() && assistant_state)
     assistant_state->RemoveObserver(this);
 }
@@ -430,7 +431,7 @@
 bool SearchSection::IsAssistantAllowed() const {
   // NOTE: This will be false when the flag is disabled.
   return ::assistant::IsAssistantAllowedForProfile(profile()) ==
-         chromeos::assistant::AssistantAllowedState::ALLOWED;
+         assistant::AssistantAllowedState::ALLOWED;
 }
 
 void SearchSection::UpdateAssistantSearchTags() {
@@ -441,7 +442,7 @@
   updater.RemoveSearchTags(GetAssistantOffSearchConcepts());
   updater.RemoveSearchTags(GetAssistantVoiceMatchSearchConcepts());
 
-  ash::AssistantState* assistant_state = ash::AssistantState::Get();
+  AssistantState* assistant_state = AssistantState::Get();
 
   // The setting_enabled() function is the top-level enabled state. If this is
   // off, none of the sub-features are enabled.
@@ -481,5 +482,4 @@
   }
 }
 
-}  // namespace settings
-}  // namespace chromeos
+}  // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/ash/search_section.h b/chrome/browser/ui/webui/settings/ash/search_section.h
index dd9aae6e..6602020 100644
--- a/chrome/browser/ui/webui/settings/ash/search_section.h
+++ b/chrome/browser/ui/webui/settings/ash/search_section.h
@@ -8,22 +8,21 @@
 #include "ash/public/cpp/assistant/assistant_state_base.h"
 #include "base/values.h"
 #include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
-// TODO(https://crbug.com/1164001): move to forward declaration
-#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h"
 #include "chromeos/components/quick_answers/public/cpp/quick_answers_state.h"
 
 namespace content {
 class WebUIDataSource;
 }  // namespace content
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
+
+class SearchTagRegistry;
 
 // Provides UI strings and search tags for Search & Assistant settings. Search
 // tags for Assistant settings are added/removed depending on whether the
 // feature and relevant flags are enabled/disabled.
 class SearchSection : public OsSettingsSection,
-                      public ash::AssistantStateObserver,
+                      public AssistantStateObserver,
                       public QuickAnswersStateObserver {
  public:
   SearchSection(Profile* profile, SearchTagRegistry* search_tag_registry);
@@ -34,13 +33,14 @@
   void AddLoadTimeData(content::WebUIDataSource* html_source) override;
   void AddHandlers(content::WebUI* web_ui) override;
   int GetSectionNameMessageId() const override;
-  mojom::Section GetSection() const override;
-  ash::settings::mojom::SearchResultIcon GetSectionIcon() const override;
+  chromeos::settings::mojom::Section GetSection() const override;
+  mojom::SearchResultIcon GetSectionIcon() const override;
   std::string GetSectionPath() const override;
-  bool LogMetric(mojom::Setting setting, base::Value& value) const override;
+  bool LogMetric(chromeos::settings::mojom::Setting setting,
+                 base::Value& value) const override;
   void RegisterHierarchy(HierarchyGenerator* generator) const override;
 
-  // ash::AssistantStateObserver:
+  // AssistantStateObserver:
   void OnAssistantConsentStatusChanged(int consent_status) override;
   void OnAssistantContextEnabled(bool enabled) override;
   void OnAssistantSettingsEnabled(bool enabled) override;
@@ -55,12 +55,6 @@
   void UpdateQuickAnswersSearchTags();
 };
 
-}  // namespace settings
-}  // namespace chromeos
-
-// TODO(https://crbug.com/1164001): remove when it moved to ash.
-namespace ash::settings {
-using ::chromeos::settings::SearchSection;
-}
+}  // namespace ash::settings
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_SEARCH_SECTION_H_
diff --git a/chrome/browser/ui/webui/settings/ash/server_printer_url_util.cc b/chrome/browser/ui/webui/settings/ash/server_printer_url_util.cc
index 80f5108..9f9b444 100644
--- a/chrome/browser/ui/webui/settings/ash/server_printer_url_util.cc
+++ b/chrome/browser/ui/webui/settings/ash/server_printer_url_util.cc
@@ -25,8 +25,7 @@
 
 }  // namespace
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
 
 bool HasValidServerPrinterScheme(const GURL& gurl) {
   return gurl.SchemeIsHTTPOrHTTPS() || gurl.SchemeIs("ipp") ||
@@ -69,5 +68,4 @@
   return gurl->IsStandard() ? gurl : absl::nullopt;
 }
 
-}  // namespace settings
-}  // namespace chromeos
+}  // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/ash/server_printer_url_util.h b/chrome/browser/ui/webui/settings/ash/server_printer_url_util.h
index ad34064..2802e0a 100644
--- a/chrome/browser/ui/webui/settings/ash/server_printer_url_util.h
+++ b/chrome/browser/ui/webui/settings/ash/server_printer_url_util.h
@@ -11,8 +11,7 @@
 
 class GURL;
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
 
 // Returns true if |gurl| has any the following scheme: HTTP, HTTPS, IPP, or
 // IPPS. Returns false for an empty or any other scheme.
@@ -24,13 +23,6 @@
 absl::optional<GURL> GenerateServerPrinterUrlWithValidScheme(
     const std::string& url);
 
-}  // namespace settings
-}  // namespace chromeos
-
-// TODO(https://crbug.com/1164001): remove when it moved to ash.
-namespace ash::settings {
-using ::chromeos::settings::GenerateServerPrinterUrlWithValidScheme;
-using ::chromeos::settings::HasValidServerPrinterScheme;
 }  // namespace ash::settings
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_SERVER_PRINTER_URL_UTIL_H_
diff --git a/chrome/browser/ui/webui/settings/ash/server_printer_url_util_unittest.cc b/chrome/browser/ui/webui/settings/ash/server_printer_url_util_unittest.cc
index 6c9b317..0df9711 100644
--- a/chrome/browser/ui/webui/settings/ash/server_printer_url_util_unittest.cc
+++ b/chrome/browser/ui/webui/settings/ash/server_printer_url_util_unittest.cc
@@ -10,8 +10,7 @@
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
-namespace chromeos {
-namespace settings {
+namespace ash::settings {
 
 class ServerPrinterUrlUtilTest : public testing::Test {
  public:
@@ -85,5 +84,4 @@
   ASSERT_EQ("https://123.123.11.11:555/", gurl5->spec());
 }
 
-}  // namespace settings
-}  // namespace chromeos
+}  // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
index 5c53907..d645429f 100644
--- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -2475,6 +2475,8 @@
      IDS_SETTINGS_SITE_SETTINGS_CLEAR_DISPLAYED_STORAGE_DIALOG_TITLE},
     {"siteSettingsFirstPartySetsLearnMore",
      IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_LEARN_MORE},
+    {"siteSettingsFirstPartySetsLearnMoreAccessibility",
+     IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_LEARN_MORE_ACCESSIBILITY},
     {"siteSettingsClearAllStorageDescription",
      IDS_SETTINGS_SITE_SETTINGS_CLEAR_ALL_STORAGE_DESCRIPTION},
     {"siteSettingsClearDisplayedStorageDescription",
diff --git a/chrome/browser/vr/win/graphics_delegate_win.cc b/chrome/browser/vr/win/graphics_delegate_win.cc
index f7a686b2..3ef1fee 100644
--- a/chrome/browser/vr/win/graphics_delegate_win.cc
+++ b/chrome/browser/vr/win/graphics_delegate_win.cc
@@ -53,7 +53,7 @@
 
 void GraphicsDelegateWin::InitializeOnGLThread() {
   DCHECK(context_provider_);
-  if (context_provider_->BindToCurrentThread() ==
+  if (context_provider_->BindToCurrentSequence() ==
       gpu::ContextResult::kSuccess) {
     gl_ = context_provider_->ContextGL();
     sii_ = context_provider_->SharedImageInterface();
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index ca761725..da65e05 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1665683972-b231a6000fbf697649d58a61ced2a6cbf9b323c8.profdata
+chrome-linux-main-1665705175-3b87724b05b15ccb17d6b88de6a64ef8433576c9.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 18fd987..57b73f3 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1665683972-8472583865427d6bd4b39786257e09c0986f9fcc.profdata
+chrome-mac-main-1665725711-8b91ab1e08d99b7e27c06aa097e0c7f50f481cf6.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index f02b642..2484d07 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1665673120-7baff30fe58cba814b897ff8b6c341e70ec06893.profdata
+chrome-win32-main-1665725711-7a5ece51c21f206817e2bbc0fdf1b1588c007956.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 9737ab5d..4ad59698 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1665694288-62ecc6570a8a2a9bb7bd62acece4924e5b21163d.profdata
+chrome-win64-main-1665725711-da24cf4edd24a35a37c9976200a8d48955ff5023.profdata
diff --git a/chrome/renderer/BUILD.gn b/chrome/renderer/BUILD.gn
index 9d935eb..d6cce166 100644
--- a/chrome/renderer/BUILD.gn
+++ b/chrome/renderer/BUILD.gn
@@ -44,8 +44,8 @@
   }
   if (is_chromeos_ash) {
     deps += [
-      "//ash/services/ime/public/mojom:mojom_js",
       "//chromeos/ash/components/enhanced_network_tts/mojom:mojom_js",
+      "//chromeos/ash/services/ime/public/mojom:mojom_js",
       "//chromeos/services/tts/public/mojom:mojom_js",
     ]
   }
diff --git a/chrome/renderer/resources/extensions/OWNERS b/chrome/renderer/resources/extensions/OWNERS
index 6cb37996..629ed6d 100644
--- a/chrome/renderer/resources/extensions/OWNERS
+++ b/chrome/renderer/resources/extensions/OWNERS
@@ -3,7 +3,7 @@
 per-file *.gtestjs=*
 per-file automation_custom_bindings.js=dtseng@chromium.org
 per-file automation_custom_bindings.js=nektar@chromium.org
-per-file chromeos_ime_service_bindings.js=file://ash/services/ime/OWNERS
+per-file chromeos_ime_service_bindings.js=file://chromeos/ash/services/ime/OWNERS
 per-file enterprise_platform_keys*=emaxx@chromium.org
 per-file file_manager_private_custom_bindings.js=file://ui/file_manager/OWNERS
 per-file image_util.js=dewittj@chromium.org
diff --git a/chrome/renderer/resources/renderer_resources.grd b/chrome/renderer/resources/renderer_resources.grd
index c105652..742f7ae 100644
--- a/chrome/renderer/resources/renderer_resources.grd
+++ b/chrome/renderer/resources/renderer_resources.grd
@@ -71,10 +71,10 @@
 
           <!-- ChromeOS IME Mojo service and bindings. -->
           <include name="IDR_IME_SERVICE_BINDINGS_JS" file="extensions\chromeos_ime_service_bindings.js" type="BINDATA" />
-          <include name="IDR_IME_SERVICE_MOJOM_JS" file="${mojom_root}\ash\services\ime\public\mojom\ime_service.mojom.js" use_base_dir="false" type="BINDATA" />
-          <include name="IDR_IME_SERVICE_INPUT_ENGINE_MOJOM_JS" file="${mojom_root}\ash\services\ime\public\mojom\input_engine.mojom.js" use_base_dir="false" type="BINDATA" />
-          <include name="IDR_IME_SERVICE_INPUT_METHOD_MOJOM_JS" file="${mojom_root}\ash\services\ime\public\mojom\input_method.mojom.js" use_base_dir="false" type="BINDATA" />
-          <include name="IDR_IME_SERVICE_INPUT_METHOD_HOST_MOJOM_JS" file="${mojom_root}\ash\services\ime\public\mojom\input_method_host.mojom.js" use_base_dir="false" type="BINDATA" />
+          <include name="IDR_IME_SERVICE_MOJOM_JS" file="${mojom_root}\chromeos\ash\services\ime\public\mojom\ime_service.mojom.js" use_base_dir="false" type="BINDATA" />
+          <include name="IDR_IME_SERVICE_INPUT_ENGINE_MOJOM_JS" file="${mojom_root}\chromeos\ash\services\ime\public\mojom\input_engine.mojom.js" use_base_dir="false" type="BINDATA" />
+          <include name="IDR_IME_SERVICE_INPUT_METHOD_MOJOM_JS" file="${mojom_root}\chromeos\ash\services\ime\public\mojom\input_method.mojom.js" use_base_dir="false" type="BINDATA" />
+          <include name="IDR_IME_SERVICE_INPUT_METHOD_HOST_MOJOM_JS" file="${mojom_root}\chromeos\ash\services\ime\public\mojom\input_method_host.mojom.js" use_base_dir="false" type="BINDATA" />
 
           <include name="IDR_GOOGLE_TTS_STREAM_BINDINGS_JS" file="extensions\chromeos_google_tts_stream_bindings.js" type="BINDATA" />
           <include name="IDR_GOOGLE_TTS_STREAM_MOJOM_JS" file="${mojom_root}\chromeos\services\tts\public\mojom\tts_service.mojom.js" use_base_dir="false" type="BINDATA" />
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index b68fa1b..d9385d4 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -5304,6 +5304,7 @@
     "../browser/favicon/large_icon_service_factory_unittest.cc",
     "../browser/file_select_helper_unittest.cc",
     "../browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc",
+    "../browser/first_party_sets/first_party_sets_navigation_throttle_unittest.cc",
     "../browser/first_party_sets/first_party_sets_overrides_policy_handler_unittest.cc",
     "../browser/first_party_sets/first_party_sets_policy_service_factory_unittest.cc",
     "../browser/first_party_sets/first_party_sets_policy_service_unittest.cc",
@@ -9270,6 +9271,7 @@
     if (is_chromeos_lacros) {
       deps += [
         "//chromeos/lacros",
+        "//chromeos/lacros:test_support",
         "//components/account_manager_core",
         "//components/account_manager_core:test_support",
       ]
diff --git a/chrome/test/data/extensions/api_test/file_system_provider/service_worker/BUILD.gn b/chrome/test/data/extensions/api_test/file_system_provider/service_worker/BUILD.gn
index 8e51439b..ac3d1d9 100644
--- a/chrome/test/data/extensions/api_test/file_system_provider/service_worker/BUILD.gn
+++ b/chrome/test/data/extensions/api_test/file_system_provider/service_worker/BUILD.gn
@@ -16,6 +16,8 @@
 # Group for type checking.
 js_library("service_worker") {
   sources = [
+    "add_watcher/sw.js",
+    "add_watcher/test.js",
     "big_file/sw.js",
     "big_file/test.js",
     "configure/sw.js",
diff --git a/chrome/test/data/extensions/api_test/file_system_provider/service_worker/add_watcher/manifest.json b/chrome/test/data/extensions/api_test/file_system_provider/service_worker/add_watcher/manifest.json
new file mode 100644
index 0000000..7d6c56e
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/file_system_provider/service_worker/add_watcher/manifest.json
@@ -0,0 +1,24 @@
+{
+  // chrome-extension://pkplfbidichfdicaijlchgnapepdginl
+  "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtDfX9dHNh948bt00YhZBm3P6E5QLaOt+v8kXVtibQfiPtOD2FTScB/f0wX/EQWVO7BkaSOsRkTPcPIgocyMPYr2FLgqGLFlYT9nQpKJZUFNF5oJ5rG6Nv7ppf4zEB3j6da1IBRTz2yOZ+6O1TMZxol/V62/QcqrJeggsHTEPGLdr9Ua4b1Ka0xKJnJngZljsbw93FI1o+P9dAh5BS6wTPiZI/vmJVjvMTkSTnaZ3n9Go2t7A0XLcSxLcVyuLAd2mAvSN0mIviOukdM66wr7llif71nKuUt+4qvlr/r9HfwzN6pA4jkwhtS1UD+3CmB+wsHwsnohNcuu4FIQ6rgq/7QIDAQAB",
+  "name": "chrome.fileSystemProvider.onAddWatcherRequested",
+  "version": "0.1",
+  "manifest_version": 3,
+  "description":
+      "Test for chrome.fileSystemProvider.onAddWatcherRequested() for service workers.",
+  "permissions": [
+    "fileSystemProvider",
+    {
+      "fileSystem": ["requestFileSystem", "write"]
+    },
+    "fileManagerPrivate"
+  ],
+  "file_system_provider_capabilities": {
+    "watchable": true,
+    "source": "device"
+  },
+  "background": {
+    "service_worker": "sw.js",
+    "type": "module"
+  }
+}
diff --git a/chrome/test/data/extensions/api_test/file_system_provider/service_worker/add_watcher/sw.js b/chrome/test/data/extensions/api_test/file_system_provider/service_worker/add_watcher/sw.js
new file mode 100644
index 0000000..ac074135
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/file_system_provider/service_worker/add_watcher/sw.js
@@ -0,0 +1,7 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {serviceWorkerMain} from '/_test_resources/api_test/file_system_provider/service_worker/provider.js';
+
+serviceWorkerMain(self);
diff --git a/chrome/test/data/extensions/api_test/file_system_provider/service_worker/add_watcher/test.html b/chrome/test/data/extensions/api_test/file_system_provider/service_worker/add_watcher/test.html
new file mode 100644
index 0000000..9980fda0
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/file_system_provider/service_worker/add_watcher/test.html
@@ -0,0 +1 @@
+<script type="module" src="test.js"></script>
diff --git a/chrome/test/data/extensions/api_test/file_system_provider/service_worker/add_watcher/test.js b/chrome/test/data/extensions/api_test/file_system_provider/service_worker/add_watcher/test.js
new file mode 100644
index 0000000..82582c97
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/file_system_provider/service_worker/add_watcher/test.js
@@ -0,0 +1,95 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {getAllFsInfos, mountTestFileSystem, promisifyWithLastError} from '/_test_resources/api_test/file_system_provider/service_worker/helpers.js';
+import {TestFileSystemProvider} from '/_test_resources/api_test/file_system_provider/service_worker/provider.js';
+
+/** @param {!Entry} entry */
+async function addFileWatch(entry) {
+  return promisifyWithLastError(chrome.fileManagerPrivate.addFileWatch, entry);
+}
+
+async function main() {
+  await navigator.serviceWorker.ready;
+
+  const fileSystem = await mountTestFileSystem();
+  const fileName = TestFileSystemProvider.FILE_READ_SUCCESS;
+
+  chrome.test.runTests([
+    // Add an entry watcher on an existing file.
+    async function addWatcher() {
+      try {
+        const fileEntry =
+            await fileSystem.getFileEntry(fileName, {create: false});
+        const watching = await addFileWatch(fileEntry);
+        chrome.test.assertTrue(watching);
+
+        const fsInfos = await getAllFsInfos();
+
+        chrome.test.assertEq(1, fsInfos.length);
+        chrome.test.assertEq(1, fsInfos[0].watchers.length);
+        const watcher = fsInfos[0].watchers[0];
+        chrome.test.assertEq('/' + fileName, watcher.entryPath);
+        chrome.test.assertFalse(watcher.recursive);
+        chrome.test.assertEq(undefined, /**@type {!Object} */ (watcher).tag);
+
+        chrome.test.succeed();
+      } catch (error) {
+        chrome.test.fail(error);
+      }
+    },
+
+    // Add an entry watcher on a file which is already watched, it should fail.
+    async function addExistingFileWatcher() {
+      try {
+        // Should start with one watcher.
+        let fsInfos = await getAllFsInfos();
+        chrome.test.assertEq(1, fsInfos.length);
+        chrome.test.assertEq(1, fsInfos[0].watchers.length);
+
+        const fileEntry =
+            await fileSystem.getFileEntry(fileName, {create: false});
+        try {
+          await addFileWatch(fileEntry);
+          chrome.test.fail('Adding file watcher should have failed.');
+        } catch (error) {
+          chrome.test.assertEq('Unknown error.', error.message);
+
+          // Shouldn't change the number of watchers.
+          fsInfos = await getAllFsInfos();
+          chrome.test.assertEq(1, fsInfos.length);
+          chrome.test.assertEq(1, fsInfos[0].watchers.length);
+
+          chrome.test.succeed();
+        }
+      } catch (error) {
+        chrome.test.fail(error);
+      }
+    },
+
+    // Add an entry watcher on a broken file, it should fail.
+    async function addBrokenFileWatcher() {
+      try {
+        const fileEntry = await fileSystem.getFileEntry(
+            TestFileSystemProvider.FILE_FAIL, {create: false});
+        try {
+          await addFileWatch(fileEntry);
+          chrome.test.fail('Adding file watcher should have failed.');
+        } catch (error) {
+          chrome.test.assertEq('Unknown error.', error.message);
+          // Shouldn't change the number of watchers.
+          const fsInfos = await getAllFsInfos();
+          chrome.test.assertEq(1, fsInfos.length);
+          chrome.test.assertEq(1, fsInfos[0].watchers.length);
+
+          chrome.test.succeed();
+        }
+      } catch (error) {
+        chrome.test.fail(error);
+      }
+    }
+  ]);
+}
+
+main();
diff --git a/chrome/test/data/extensions/api_test/file_system_provider/service_worker/get_all/test.js b/chrome/test/data/extensions/api_test/file_system_provider/service_worker/get_all/test.js
index c4ea7b6..d62348d 100644
--- a/chrome/test/data/extensions/api_test/file_system_provider/service_worker/get_all/test.js
+++ b/chrome/test/data/extensions/api_test/file_system_provider/service_worker/get_all/test.js
@@ -2,39 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {mountTestFileSystem, openFile, remoteProvider, startReadTextFromBlob} from '/_test_resources/api_test/file_system_provider/service_worker/helpers.js';
+import {getAllFsInfos, getFsInfoById, mountTestFileSystem, openFile, remoteProvider, startReadTextFromBlob, unmount} from '/_test_resources/api_test/file_system_provider/service_worker/helpers.js';
 // For shared constants.
 import {TestFileSystemProvider} from '/_test_resources/api_test/file_system_provider/service_worker/provider.js';
 
-// Wrappers for chrome.fileSystemProvider.* are still needed for Closure to
-// work, as it's not aware they are returning promises if callbacks are omitted.
-
-/**
- * @returns {!Promise<!Array<!chrome.fileSystemProvider.FileSystemInfo>>}
- * @suppress {checkTypes}
- */
-async function getAllFsInfos() {
-  return chrome.fileSystemProvider.getAll();
-}
-
-/**
- * @param {string} fileSystemId
- * @returns {!Promise<!chrome.fileSystemProvider.FileSystemInfo>}
- * @suppress {checkTypes}
- */
-async function getFsInfoById(fileSystemId) {
-  return chrome.fileSystemProvider.get(fileSystemId);
-}
-
-/**
- * @param {string} fileSystemId
- * @returns {!Promise<void>}
- * @suppress {checkTypes}
- */
-async function unmount(fileSystemId) {
-  return chrome.fileSystemProvider.unmount({fileSystemId});
-}
-
 async function main() {
   await navigator.serviceWorker.ready;
 
@@ -110,7 +81,6 @@
     async function mountError() {
       try {
         try {
-          /** @suppress {checkTypes} */
           await chrome.fileSystemProvider.mount(
               {fileSystemId: '', displayName: ''});
           chrome.test.fail('Mount operation should have failed.');
diff --git a/chrome/test/data/extensions/api_test/file_system_provider/service_worker/helpers.js b/chrome/test/data/extensions/api_test/file_system_provider/service_worker/helpers.js
index f1cce7ad..fbdcf29 100644
--- a/chrome/test/data/extensions/api_test/file_system_provider/service_worker/helpers.js
+++ b/chrome/test/data/extensions/api_test/file_system_provider/service_worker/helpers.js
@@ -43,6 +43,36 @@
 };
 
 /**
+ * Wrappers for chrome.fileSystemProvider.* are still needed for Closure to
+ * work, as it's not aware they are returning promises if callbacks are omitted.
+ * @returns {!Promise<!Array<!chrome.fileSystemProvider.FileSystemInfo>>}
+ * @suppress {checkTypes}
+ */
+export async function getAllFsInfos() {
+  return chrome.fileSystemProvider.getAll();
+}
+
+/**
+ * Async wrapper.
+ * @param {string} fileSystemId
+ * @returns {!Promise<void>}
+ * @suppress {checkTypes}
+ */
+export async function unmount(fileSystemId) {
+  return chrome.fileSystemProvider.unmount({fileSystemId});
+}
+
+/**
+ * Async wrapper.
+ * @param {string} fileSystemId
+ * @returns {!Promise<!chrome.fileSystemProvider.FileSystemInfo>}
+ * @suppress {checkTypes}
+ */
+export async function getFsInfoById(fileSystemId) {
+  return chrome.fileSystemProvider.get(fileSystemId);
+}
+
+/**
  * @param {number=} openedFilesLimit Limit of opened files at once. If 0 or
  *     unspecified, then not limited.
  * @returns {!Promise<{fileSystem: !FileSystem, volumeInfo:
diff --git a/chrome/test/data/extensions/api_test/file_system_provider/service_worker/provider.js b/chrome/test/data/extensions/api_test/file_system_provider/service_worker/provider.js
index cc45e7c..3652b7ca 100644
--- a/chrome/test/data/extensions/api_test/file_system_provider/service_worker/provider.js
+++ b/chrome/test/data/extensions/api_test/file_system_provider/service_worker/provider.js
@@ -492,6 +492,11 @@
       return;
     }
 
+    if (options.entryPath === '/' + TestFileSystemProvider.FILE_FAIL) {
+      onError(chrome.fileSystemProvider.ProviderError.FAILED);
+      return;
+    }
+
     if (this.findEntryByPath(options.entryPath)) {
       onSuccess();
       return;
@@ -996,7 +1001,7 @@
 TestFileSystemProvider.FILESYSTEM_ID = 'test-fs';
 
 /**
- * Reads and writes of this file always fail.
+ * Reads, writes and add/remove watchers of this file always fail.
  *
  * @type {string}
  * @const
diff --git a/chrome/test/data/privacy_budget/calls_service_worker_with_two_clients.html b/chrome/test/data/privacy_budget/calls_service_worker_with_two_clients.html
new file mode 100644
index 0000000..176e9ca
--- /dev/null
+++ b/chrome/test/data/privacy_budget/calls_service_worker_with_two_clients.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Privacy Budget: Test page that registers two clients to the same Service Worker</title>
+<script src="test_utils.js"></script>
+<script>
+  navigator.serviceWorker.register("two_clients_service_worker.js");
+
+  navigator.serviceWorker.addEventListener("message", (event) => {
+    sendValueToTest('Done');
+    navigator.serviceWorker.ready.then((registration) => {
+      // Unregister the worker to flush out the metrics.
+      registration.unregister();
+    });
+  });
+
+  navigator.serviceWorker.ready.then((registration) => {
+    registration.active.postMessage("Start");
+  });
+</script>
+
+<body>
+  <iframe src="./iframe_service_worker.html" title="Second Client"></iframe>
+</body>
diff --git a/chrome/test/data/privacy_budget/calls_shared_worker_with_two_clients.html b/chrome/test/data/privacy_budget/calls_shared_worker_with_two_clients.html
new file mode 100644
index 0000000..e1202dc
--- /dev/null
+++ b/chrome/test/data/privacy_budget/calls_shared_worker_with_two_clients.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Privacy Budget: Test page that registers two clients to the same shared worker</title>
+<script src="test_utils.js"></script>
+<script>
+  const myWorker = new SharedWorker('two_clients_shared_worker.js');
+  myWorker.port.onmessage = (e) => {
+    sendValueToTest('Done');
+  }
+  myWorker.port.postMessage('Start');
+</script>
+
+<body>
+  <iframe src="./iframe_shared_worker.html" title="Second Client"></iframe>
+</body>
diff --git a/chrome/test/data/privacy_budget/iframe_service_worker.html b/chrome/test/data/privacy_budget/iframe_service_worker.html
new file mode 100644
index 0000000..157ae4b
--- /dev/null
+++ b/chrome/test/data/privacy_budget/iframe_service_worker.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Privacy Budget: Test page used as iframe to add a client to service worker</title>
+<script src="test_utils.js"></script>
+<script language="javascript">
+  navigator.serviceWorker.register("two_clients_service_worker.js");
+
+  navigator.serviceWorker.addEventListener("message", (event) => {
+    sendValueToTest('Done');
+    navigator.serviceWorker.ready.then((registration) => {
+      // Unregister the worker to flush out the metrics.
+      registration.unregister();
+    });
+  });
+
+  navigator.serviceWorker.ready.then((registration) => {
+    registration.active.postMessage("Start");
+  });
+</script>
diff --git a/chrome/test/data/privacy_budget/iframe_shared_worker.html b/chrome/test/data/privacy_budget/iframe_shared_worker.html
new file mode 100644
index 0000000..7baaa36
--- /dev/null
+++ b/chrome/test/data/privacy_budget/iframe_shared_worker.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Privacy Budget: Test page used as an iframe to add a client to a shared worker</title>
+<script src="test_utils.js"></script>
+<script language="javascript">
+  const myWorker = new SharedWorker('two_clients_shared_worker.js');
+  myWorker.port.onmessage = (e) => {
+    sendValueToTest('Done');
+  }
+  myWorker.port.postMessage('Start');
+</script>
diff --git a/chrome/test/data/privacy_budget/two_clients_service_worker.js b/chrome/test/data/privacy_budget/two_clients_service_worker.js
new file mode 100644
index 0000000..372e88c3
--- /dev/null
+++ b/chrome/test/data/privacy_budget/two_clients_service_worker.js
@@ -0,0 +1,14 @@
+// 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.
+
+self.addEventListener("message", async () => {
+  const clients = await self.clients.matchAll({
+    includeUncontrolled: true,
+    type: "all",
+  });
+
+  if (clients.length == 2) {
+    clients.forEach(client => client.postMessage("Done"));
+  }
+});
diff --git a/chrome/test/data/privacy_budget/two_clients_shared_worker.js b/chrome/test/data/privacy_budget/two_clients_shared_worker.js
new file mode 100644
index 0000000..9415779
--- /dev/null
+++ b/chrome/test/data/privacy_budget/two_clients_shared_worker.js
@@ -0,0 +1,19 @@
+// 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.
+
+var clients_ports = [];
+
+onconnect = (e) => {
+  const port = e.ports[0];
+  clients_ports.push(port);
+  port.onmessage = (e) => {
+    if (e.data == "close") {
+      // Close the worker to flush out the metrics.
+      self.close();
+    } else if (clients_ports.length == 2) {
+      clients_ports[0].postMessage("Done");
+      clients_ports[1].postMessage("Done");
+    }
+  }
+}
diff --git a/chrome/test/data/webui/chromeos/os_feedback_ui/search_page_test.js b/chrome/test/data/webui/chromeos/os_feedback_ui/search_page_test.js
index 94723358..88a70dd2 100644
--- a/chrome/test/data/webui/chromeos/os_feedback_ui/search_page_test.js
+++ b/chrome/test/data/webui/chromeos/os_feedback_ui/search_page_test.js
@@ -108,6 +108,7 @@
    *   not triggered.
    * - Case 2: When number of characters newly entered is 3 or more, search is
    *   triggered and help contents are populated.
+   * - Case 3: When the text area is empty, search is NOT triggered.
    */
   test('HelpContentPopulated', async () => {
     /** {?Element} */
@@ -124,6 +125,7 @@
         'Share your feedback or describe your issue. ' +
             'If possible, include steps to reproduce your issue.',
         textAreaElement.placeholder);
+    assertTrue(page.getIsPopularContentForTesting_());
 
     // Enter three chars.
     textAreaElement.value = 'abc';
@@ -134,6 +136,7 @@
     await flushTasks();
     // Verify that getHelpContent() has been called with query 'abc'.
     assertEquals('abc', provider.lastQuery);
+    assertFalse(page.getIsPopularContentForTesting_());
 
     // Enter 2 more characters. This should NOT trigger another search.
     textAreaElement.value = 'abc12';
@@ -151,6 +154,18 @@
     await flushTasks();
     // Verify that getHelpContent() has been called with query 'abc123'.
     assertEquals('abc123', provider.lastQuery);
+    assertFalse(page.getIsPopularContentForTesting_());
+
+    // Remove all the text area characters. This should NOT trigger
+    // getHelpContent().
+    textAreaElement.value = '';
+    textAreaElement.dispatchEvent(new Event('input'));
+    await flushTasks();
+
+    // Verify that getHelpContent() is not called, and the help content
+    // is the default popular content.
+    assertNotEquals('', provider.lastQuery);
+    assertTrue(page.getIsPopularContentForTesting_());
   });
 
   test('HelpContentSearchResultCountColdStart', async () => {
diff --git a/chrome/test/data/webui/settings/all_sites_tests.ts b/chrome/test/data/webui/settings/all_sites_tests.ts
index 89eee5b..546ff4cc 100644
--- a/chrome/test/data/webui/settings/all_sites_tests.ts
+++ b/chrome/test/data/webui/settings/all_sites_tests.ts
@@ -1342,10 +1342,13 @@
         fpsLearnMore =
             testElement.shadowRoot!.querySelector<HTMLElement>('#fpsLearnMore');
         assertFalse(fpsLearnMore!.hidden);
-        const textContainer = testElement.shadowRoot!
-                                  .querySelector<HTMLElement>(
-                                      'localized-link')!.shadowRoot!.innerHTML;
-        assertTrue(textContainer.search('foo.com') !== -1);
+        assertEquals(
+            [
+              loadTimeData.getStringF(
+                  'siteSettingsFirstPartySetsLearnMore', 'foo.com'),
+              loadTimeData.getString('learnMore'),
+            ].join(' '),
+            fpsLearnMore!.innerText.trim());
 
         testElement.filter = 'related:bar.com';
         flush();
diff --git a/chrome/test/data/webui/settings/chromeos/smart_privacy_subpage_tests.js b/chrome/test/data/webui/settings/chromeos/smart_privacy_subpage_tests.js
index 4b60982f..1ebc926 100644
--- a/chrome/test/data/webui/settings/chromeos/smart_privacy_subpage_tests.js
+++ b/chrome/test/data/webui/settings/chromeos/smart_privacy_subpage_tests.js
@@ -16,12 +16,13 @@
 
   /**
    * Generate preferences for the smart privacy page that either enable or
-   * disable the snooping protection feature.
-   * @ param {boolean} state Whether to enable or disable.
+   * disable the quick dim or snooping protection feature.
+   * @ param {boolean} quickDimState To enable or disable quick dim.
+   * @ param {boolean} snoopingState To enable or disable snooping protection.
    * @return {!CrSettingsPrefs} The corresponding pref dictionary.
    * @private
    */
-  function makePrefs(snoopingState) {
+  function makePrefs(quickDimState, snoopingState) {
     return {
       'ash': {
         'privacy': {
@@ -30,19 +31,25 @@
           },
         },
       },
+      'power': {
+        'quick_dim_enabled': {
+          value: quickDimState,
+        },
+      },
     };
   }
 
   setup(async () => {
-    // Options aren't shown unless the snooping protection feature is enabled.
+    // Options aren't shown unless the feature is enabled.
     loadTimeData.overrideValues({
+      isQuickDimEnabled: true,
       isSnoopingProtectionEnabled: true,
     });
 
     PolymerTest.clearBody();
     smartPrivacySubpage = document.createElement('settings-smart-privacy-page');
     assertTrue(!!smartPrivacySubpage);
-    smartPrivacySubpage.prefs = makePrefs(false);
+    smartPrivacySubpage.prefs = makePrefs(false, false);
     document.body.appendChild(smartPrivacySubpage);
   });
 
@@ -61,7 +68,23 @@
     assertFalse(collapse.opened);
 
     // Atomic reassign to so that Polymer notices the change.
-    smartPrivacySubpage.prefs = makePrefs(true);
+    smartPrivacySubpage.prefs = makePrefs(false, true);
+    flush();
+
+    assertTrue(collapse.opened);
+  });
+
+  test('Quick dim slider visibility tied to pref', async () => {
+    // The $ method won't find elements inside templates.
+    /** @type {?HTMLElement} */
+    const collapse =
+        smartPrivacySubpage.shadowRoot.querySelector('#quickDimOptions');
+
+    // Default pref value is false.
+    assertFalse(collapse.opened);
+
+    // Atomic reassign to so that Polymer notices the change.
+    smartPrivacySubpage.prefs = makePrefs(true, false);
     flush();
 
     assertTrue(collapse.opened);
diff --git a/chrome/test/data/webui/test_api.js b/chrome/test/data/webui/test_api.js
index 89614e4..9cbe4a0 100644
--- a/chrome/test/data/webui/test_api.js
+++ b/chrome/test/data/webui/test_api.js
@@ -26,11 +26,6 @@
 var testing = {};
 (function(exports) {
 /**
- * Holds the original version of the |chrome| object.
- */
-const originalChrome = null;
-
-/**
  * Hold the currentTestCase across between preLoad and run.
  * @type {TestCase}
  */
diff --git a/chrome/utility/BUILD.gn b/chrome/utility/BUILD.gn
index cf4a826..c41cbfd 100644
--- a/chrome/utility/BUILD.gn
+++ b/chrome/utility/BUILD.gn
@@ -182,8 +182,6 @@
 
   if (is_chromeos_ash) {
     deps += [
-      "//ash/services/ime:lib",
-      "//ash/services/ime/public/mojom",
       "//chrome/services/file_util",
       "//chrome/services/sharing",
       "//chromeos/ash/components/assistant:buildflags",
@@ -191,6 +189,8 @@
       "//chromeos/ash/components/local_search_service/public/mojom",
       "//chromeos/ash/components/trash_service",
       "//chromeos/ash/components/trash_service/public/mojom",
+      "//chromeos/ash/services/ime:lib",
+      "//chromeos/ash/services/ime/public/mojom",
       "//chromeos/ash/services/nearby/public/mojom:mojom",
       "//chromeos/ash/services/quick_pair",
       "//chromeos/ash/services/recording",
diff --git a/chrome/utility/DEPS b/chrome/utility/DEPS
index 4b79cbb..5144ee2 100644
--- a/chrome/utility/DEPS
+++ b/chrome/utility/DEPS
@@ -1,6 +1,4 @@
 include_rules = [
-  "+ash/services/ime/ime_service.h",
-  "+ash/services/ime/public/mojom",
   "+chrome/grit",
   "+chrome/installer/util",
   "+chrome/services/ipp_parser/ipp_parser.h",
@@ -32,6 +30,8 @@
   "+chromeos/ash/components/trash_service/public/mojom",
   "+chromeos/ash/services/assistant",
   "+chromeos/ash/services/assistant/audio_decoder",
+  "+chromeos/ash/services/ime/ime_service.h",
+  "+chromeos/ash/services/ime/public/mojom",
   "+chromeos/ash/services/libassistant/libassistant_service.h",
   "+chromeos/ash/services/nearby",
   "+chromeos/ash/services/recording/recording_service.h",
diff --git a/chrome/utility/services.cc b/chrome/utility/services.cc
index 456d520..39142828 100644
--- a/chrome/utility/services.cc
+++ b/chrome/utility/services.cc
@@ -118,14 +118,14 @@
 #include "components/services/paint_preview_compositor/public/mojom/paint_preview_compositor.mojom.h"
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-#include "ash/services/ime/ime_service.h"
-#include "ash/services/ime/public/mojom/input_engine.mojom.h"
 #include "chrome/services/sharing/sharing_impl.h"
 #include "chromeos/ash/components/assistant/buildflags.h"  // nogncheck
 #include "chromeos/ash/components/local_search_service/local_search_service.h"
 #include "chromeos/ash/components/local_search_service/public/mojom/local_search_service.mojom.h"
 #include "chromeos/ash/components/trash_service/public/mojom/trash_service.mojom.h"
 #include "chromeos/ash/components/trash_service/trash_service_impl.h"
+#include "chromeos/ash/services/ime/ime_service.h"
+#include "chromeos/ash/services/ime/public/mojom/input_engine.mojom.h"
 #include "chromeos/ash/services/nearby/public/mojom/sharing.mojom.h"  // nogncheck
 #include "chromeos/ash/services/quick_pair/quick_pair_service.h"
 #include "chromeos/ash/services/recording/recording_service.h"
diff --git a/chromecast/media/gpu/cast_gpu_factory_impl.cc b/chromecast/media/gpu/cast_gpu_factory_impl.cc
index 95bb6c2f..7065a2a5 100644
--- a/chromecast/media/gpu/cast_gpu_factory_impl.cc
+++ b/chromecast/media/gpu/cast_gpu_factory_impl.cc
@@ -291,7 +291,7 @@
       viz::command_buffer_metrics::ContextType::MEDIA);
   DCHECK(context_provider_);
 
-  if (context_provider_->BindToCurrentThread() !=
+  if (context_provider_->BindToCurrentSequence() !=
       gpu::ContextResult::kSuccess) {
     LOG(ERROR) << "Failed to bind ContextProvider to current thread";
     context_provider_ = nullptr;
diff --git a/chromecast/renderer/cast_content_renderer_client.cc b/chromecast/renderer/cast_content_renderer_client.cc
index ae3bd59..6ef3ff4a 100644
--- a/chromecast/renderer/cast_content_renderer_client.cc
+++ b/chromecast/renderer/cast_content_renderer_client.cc
@@ -297,7 +297,7 @@
 CastContentRendererClient::OverrideDemuxerForUrl(
     content::RenderFrame* render_frame,
     const GURL& url,
-    scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
+    scoped_refptr<base::SequencedTaskRunner> task_runner) {
   if (render_frame->GetRenderFrameMediaPlaybackOptions()
           .is_remoting_renderer_enabled() &&
       url.SchemeIs(::media::remoting::kRemotingScheme)) {
diff --git a/chromecast/renderer/cast_content_renderer_client.h b/chromecast/renderer/cast_content_renderer_client.h
index 42493fb..014aae33c 100644
--- a/chromecast/renderer/cast_content_renderer_client.h
+++ b/chromecast/renderer/cast_content_renderer_client.h
@@ -8,6 +8,7 @@
 #include <memory>
 #include <vector>
 
+#include "base/task/sequenced_task_runner.h"
 #include "build/build_config.h"
 #include "chromecast/chromecast_buildflags.h"
 #include "chromecast/common/mojom/application_media_capabilities.mojom.h"
@@ -65,7 +66,7 @@
   std::unique_ptr<::media::Demuxer> OverrideDemuxerForUrl(
       content::RenderFrame* render_frame,
       const GURL& url,
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner) override;
+      scoped_refptr<base::SequencedTaskRunner> task_runner) override;
   bool IsIdleMediaSuspendEnabled() override;
   void SetRuntimeFeaturesDefaultsBeforeBlinkInitialization() override;
   std::unique_ptr<blink::WebSocketHandshakeThrottleProvider>
diff --git a/chromeos/ash/services/BUILD.gn b/chromeos/ash/services/BUILD.gn
index 8636191..36568e558 100644
--- a/chromeos/ash/services/BUILD.gn
+++ b/chromeos/ash/services/BUILD.gn
@@ -26,6 +26,8 @@
     "//chromeos/ash/services/cros_healthd/public/cpp:unit_tests",
     "//chromeos/ash/services/federated/public/cpp:unit_tests",
     "//chromeos/ash/services/hotspot_config:unit_tests",
+    "//chromeos/ash/services/ime:services_unittests",
+    "//chromeos/ash/services/ime:unit_tests",
     "//chromeos/ash/services/nearby/public/cpp:unit_tests",
     "//chromeos/ash/services/quick_pair:unit_tests",
     "//chromeos/services/machine_learning/public/cpp:ash_unit_tests",
diff --git a/ash/services/ime/BUILD.gn b/chromeos/ash/services/ime/BUILD.gn
similarity index 80%
rename from ash/services/ime/BUILD.gn
rename to chromeos/ash/services/ime/BUILD.gn
index cc18a39..b94fbbc 100644
--- a/ash/services/ime/BUILD.gn
+++ b/chromeos/ash/services/ime/BUILD.gn
@@ -28,8 +28,8 @@
   deps = [
     ":constants",
     "//ash/constants",
-    "//ash/services/ime/public/cpp/shared_lib:interfaces",
     "//base",
+    "//chromeos/ash/services/ime/public/cpp/shared_lib:interfaces",
   ]
 }
 
@@ -51,10 +51,10 @@
     ":constants",
     ":decoder",
     "//ash/constants",
-    "//ash/services/ime/public/cpp:rulebased",
-    "//ash/services/ime/public/cpp/shared_lib:interfaces",
-    "//ash/services/ime/public/mojom",
     "//base",
+    "//chromeos/ash/services/ime/public/cpp:rulebased",
+    "//chromeos/ash/services/ime/public/cpp/shared_lib:interfaces",
+    "//chromeos/ash/services/ime/public/mojom",
   ]
 }
 
@@ -75,7 +75,7 @@
 
 source_set("unit_tests") {
   testonly = true
-  deps = [ "//ash/services/ime/public/cpp:rulebased_unit_tests" ]
+  deps = [ "//chromeos/ash/services/ime/public/cpp:rulebased_unit_tests" ]
 }
 
 source_set("services_unittests") {
@@ -84,10 +84,10 @@
     ":lib",
     ":test_support",
     "//ash/constants",
-    "//ash/services/ime:decoder",
-    "//ash/services/ime/public/mojom",
     "//base",
     "//base/test:test_support",
+    "//chromeos/ash/services/ime:decoder",
+    "//chromeos/ash/services/ime/public/mojom",
     "//mojo/public/cpp/bindings",
     "//services/network:test_support",
     "//testing/gmock",
@@ -106,7 +106,7 @@
     "mock_input_channel.h",
   ]
   deps = [
-    "//ash/services/ime/public/mojom",
+    "//chromeos/ash/services/ime/public/mojom",
     "//testing/gmock",
   ]
 }
diff --git a/ash/services/ime/DEPS b/chromeos/ash/services/ime/DEPS
similarity index 100%
rename from ash/services/ime/DEPS
rename to chromeos/ash/services/ime/DEPS
diff --git a/ash/services/ime/DIR_METADATA b/chromeos/ash/services/ime/DIR_METADATA
similarity index 100%
rename from ash/services/ime/DIR_METADATA
rename to chromeos/ash/services/ime/DIR_METADATA
diff --git a/ash/services/ime/OWNERS b/chromeos/ash/services/ime/OWNERS
similarity index 100%
rename from ash/services/ime/OWNERS
rename to chromeos/ash/services/ime/OWNERS
diff --git a/ash/services/ime/README.md b/chromeos/ash/services/ime/README.md
similarity index 100%
rename from ash/services/ime/README.md
rename to chromeos/ash/services/ime/README.md
diff --git a/ash/services/ime/connection_factory.cc b/chromeos/ash/services/ime/connection_factory.cc
similarity index 95%
rename from ash/services/ime/connection_factory.cc
rename to chromeos/ash/services/ime/connection_factory.cc
index 0858b35..166c7c7 100644
--- a/ash/services/ime/connection_factory.cc
+++ b/chromeos/ash/services/ime/connection_factory.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 "ash/services/ime/connection_factory.h"
+#include "chromeos/ash/services/ime/connection_factory.h"
 
 #include <utility>
 
diff --git a/ash/services/ime/connection_factory.h b/chromeos/ash/services/ime/connection_factory.h
similarity index 79%
rename from ash/services/ime/connection_factory.h
rename to chromeos/ash/services/ime/connection_factory.h
index 1b06813..079a145 100644
--- a/ash/services/ime/connection_factory.h
+++ b/chromeos/ash/services/ime/connection_factory.h
@@ -2,16 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ASH_SERVICES_IME_CONNECTION_FACTORY_H_
-#define ASH_SERVICES_IME_CONNECTION_FACTORY_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_CONNECTION_FACTORY_H_
+#define CHROMEOS_ASH_SERVICES_IME_CONNECTION_FACTORY_H_
 
 #include <memory>
 #include <string>
 
-#include "ash/services/ime/public/mojom/connection_factory.mojom.h"
-#include "ash/services/ime/public/mojom/input_method.mojom.h"
-#include "ash/services/ime/public/mojom/input_method_host.mojom.h"
-#include "ash/services/ime/rule_based_engine.h"
+#include "chromeos/ash/services/ime/public/mojom/connection_factory.mojom.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method.mojom.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method_host.mojom.h"
+#include "chromeos/ash/services/ime/rule_based_engine.h"
 #include "mojo/public/cpp/bindings/pending_associated_receiver.h"
 #include "mojo/public/cpp/bindings/pending_associated_remote.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
@@ -54,4 +54,4 @@
 }  // namespace ime
 }  // namespace ash
 
-#endif  // ASH_SERVICES_IME_CONNECTION_FACTORY_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_CONNECTION_FACTORY_H_
diff --git a/ash/services/ime/constants.cc b/chromeos/ash/services/ime/constants.cc
similarity index 96%
rename from ash/services/ime/constants.cc
rename to chromeos/ash/services/ime/constants.cc
index 29c87d8..d89277d8 100644
--- a/ash/services/ime/constants.cc
+++ b/chromeos/ash/services/ime/constants.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 "ash/services/ime/constants.h"
+#include "chromeos/ash/services/ime/constants.h"
 
 #include <string.h>
 
diff --git a/ash/services/ime/constants.h b/chromeos/ash/services/ime/constants.h
similarity index 89%
rename from ash/services/ime/constants.h
rename to chromeos/ash/services/ime/constants.h
index 929b0b5..30630c2 100644
--- a/ash/services/ime/constants.h
+++ b/chromeos/ash/services/ime/constants.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 ASH_SERVICES_IME_CONSTANTS_H_
-#define ASH_SERVICES_IME_CONSTANTS_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_CONSTANTS_H_
+#define CHROMEOS_ASH_SERVICES_IME_CONSTANTS_H_
 
 #include "base/component_export.h"
 #include "base/files/file_path.h"
@@ -37,4 +37,4 @@
 }  // namespace ime
 }  // namespace ash
 
-#endif  // ASH_SERVICES_IME_CONSTANTS_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_CONSTANTS_H_
diff --git a/ash/services/ime/decoder/decoder_engine.cc b/chromeos/ash/services/ime/decoder/decoder_engine.cc
similarity index 96%
rename from ash/services/ime/decoder/decoder_engine.cc
rename to chromeos/ash/services/ime/decoder/decoder_engine.cc
index a99df67..e705291 100644
--- a/ash/services/ime/decoder/decoder_engine.cc
+++ b/chromeos/ash/services/ime/decoder/decoder_engine.cc
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ash/services/ime/decoder/decoder_engine.h"
+#include "chromeos/ash/services/ime/decoder/decoder_engine.h"
 
-#include "ash/services/ime/constants.h"
 #include "base/callback_helpers.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
+#include "chromeos/ash/services/ime/constants.h"
 
 namespace ash {
 namespace ime {
diff --git a/ash/services/ime/decoder/decoder_engine.h b/chromeos/ash/services/ime/decoder/decoder_engine.h
similarity index 79%
rename from ash/services/ime/decoder/decoder_engine.h
rename to chromeos/ash/services/ime/decoder/decoder_engine.h
index 55da6ff6..edaa4dc2 100644
--- a/ash/services/ime/decoder/decoder_engine.h
+++ b/chromeos/ash/services/ime/decoder/decoder_engine.h
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ASH_SERVICES_IME_DECODER_DECODER_ENGINE_H_
-#define ASH_SERVICES_IME_DECODER_DECODER_ENGINE_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_DECODER_DECODER_ENGINE_H_
+#define CHROMEOS_ASH_SERVICES_IME_DECODER_DECODER_ENGINE_H_
 
-#include "ash/services/ime/ime_decoder.h"
-#include "ash/services/ime/public/cpp/shared_lib/interfaces.h"
-#include "ash/services/ime/public/mojom/input_engine.mojom.h"
-#include "ash/services/ime/public/mojom/input_method.mojom.h"
-#include "ash/services/ime/public/mojom/input_method_host.mojom.h"
 #include "base/scoped_native_library.h"
+#include "chromeos/ash/services/ime/ime_decoder.h"
+#include "chromeos/ash/services/ime/public/cpp/shared_lib/interfaces.h"
+#include "chromeos/ash/services/ime/public/mojom/input_engine.mojom.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method.mojom.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method_host.mojom.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/receiver_set.h"
@@ -56,4 +56,4 @@
 }  // namespace ime
 }  // namespace ash
 
-#endif  // ASH_SERVICES_IME_DECODER_DECODER_ENGINE_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_DECODER_DECODER_ENGINE_H_
diff --git a/ash/services/ime/decoder/system_engine.cc b/chromeos/ash/services/ime/decoder/system_engine.cc
similarity index 93%
rename from ash/services/ime/decoder/system_engine.cc
rename to chromeos/ash/services/ime/decoder/system_engine.cc
index 4af9e179..a2bd3c3 100644
--- a/ash/services/ime/decoder/system_engine.cc
+++ b/chromeos/ash/services/ime/decoder/system_engine.cc
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ash/services/ime/decoder/system_engine.h"
+#include "chromeos/ash/services/ime/decoder/system_engine.h"
 
-#include "ash/services/ime/constants.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
+#include "chromeos/ash/services/ime/constants.h"
 
 namespace ash {
 namespace ime {
diff --git a/ash/services/ime/decoder/system_engine.h b/chromeos/ash/services/ime/decoder/system_engine.h
similarity index 75%
rename from ash/services/ime/decoder/system_engine.h
rename to chromeos/ash/services/ime/decoder/system_engine.h
index 2ae873c..01c23a4 100644
--- a/ash/services/ime/decoder/system_engine.h
+++ b/chromeos/ash/services/ime/decoder/system_engine.h
@@ -2,16 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ASH_SERVICES_IME_DECODER_SYSTEM_ENGINE_H_
-#define ASH_SERVICES_IME_DECODER_SYSTEM_ENGINE_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_DECODER_SYSTEM_ENGINE_H_
+#define CHROMEOS_ASH_SERVICES_IME_DECODER_SYSTEM_ENGINE_H_
 
-#include "ash/services/ime/ime_decoder.h"
-#include "ash/services/ime/public/cpp/shared_lib/interfaces.h"
-#include "ash/services/ime/public/mojom/connection_factory.mojom.h"
-#include "ash/services/ime/public/mojom/input_engine.mojom.h"
-#include "ash/services/ime/public/mojom/input_method.mojom.h"
-#include "ash/services/ime/public/mojom/input_method_host.mojom.h"
 #include "base/scoped_native_library.h"
+#include "chromeos/ash/services/ime/ime_decoder.h"
+#include "chromeos/ash/services/ime/public/cpp/shared_lib/interfaces.h"
+#include "chromeos/ash/services/ime/public/mojom/connection_factory.mojom.h"
+#include "chromeos/ash/services/ime/public/mojom/input_engine.mojom.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method.mojom.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method_host.mojom.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/receiver.h"
@@ -55,4 +55,4 @@
 }  // namespace ime
 }  // namespace ash
 
-#endif  // ASH_SERVICES_IME_DECODER_SYSTEM_ENGINE_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_DECODER_SYSTEM_ENGINE_H_
diff --git a/ash/services/ime/decoder/system_engine_unittest.cc b/chromeos/ash/services/ime/decoder/system_engine_unittest.cc
similarity index 97%
rename from ash/services/ime/decoder/system_engine_unittest.cc
rename to chromeos/ash/services/ime/decoder/system_engine_unittest.cc
index 347584c..6c1fcce1 100644
--- a/ash/services/ime/decoder/system_engine_unittest.cc
+++ b/chromeos/ash/services/ime/decoder/system_engine_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 "ash/services/ime/decoder/system_engine.h"
+#include "chromeos/ash/services/ime/decoder/system_engine.h"
 
 #include "ash/constants/ash_features.h"
 #include "base/test/bind.h"
@@ -164,6 +164,10 @@
               (mojom::KoreanSettingsPtr settings),
               (override));
   MOCK_METHOD(void,
+              ReportSuggestionOpportunity,
+              (TextSuggestionMode mode),
+              (override));
+  MOCK_METHOD(void,
               UpdateQuickSettings,
               (mojom::InputMethodQuickSettingsPtr quick_settings),
               (override));
diff --git a/ash/services/ime/ime_decoder.cc b/chromeos/ash/services/ime/ime_decoder.cc
similarity index 97%
rename from ash/services/ime/ime_decoder.cc
rename to chromeos/ash/services/ime/ime_decoder.cc
index 1f525bed..42c6329 100644
--- a/ash/services/ime/ime_decoder.cc
+++ b/chromeos/ash/services/ime/ime_decoder.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 "ash/services/ime/ime_decoder.h"
+#include "chromeos/ash/services/ime/ime_decoder.h"
 
 #include "ash/constants/ash_features.h"
-#include "ash/services/ime/constants.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
 #include "base/no_destructor.h"
+#include "chromeos/ash/services/ime/constants.h"
 
 namespace ash {
 namespace ime {
diff --git a/ash/services/ime/ime_decoder.h b/chromeos/ash/services/ime/ime_decoder.h
similarity index 91%
rename from ash/services/ime/ime_decoder.h
rename to chromeos/ash/services/ime/ime_decoder.h
index b6be0dc..4f5c8269 100644
--- a/ash/services/ime/ime_decoder.h
+++ b/chromeos/ash/services/ime/ime_decoder.h
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ASH_SERVICES_IME_IME_DECODER_H_
-#define ASH_SERVICES_IME_IME_DECODER_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_IME_DECODER_H_
+#define CHROMEOS_ASH_SERVICES_IME_IME_DECODER_H_
 
-#include "ash/services/ime/public/cpp/shared_lib/interfaces.h"
+#include "chromeos/ash/services/ime/public/cpp/shared_lib/interfaces.h"
 
 #include "base/no_destructor.h"
 #include "base/scoped_native_library.h"
@@ -15,7 +15,8 @@
 namespace ime {
 
 // START: Signatures of "C" API entry points of CrOS 1P IME shared library.
-// Must match API specs in ash/services/ime/public/cpp/shared_lib/interfaces.h
+// Must match API specs in
+// chromeos/ash/services/ime/public/cpp/shared_lib/interfaces.h
 
 inline constexpr char kSetImeEngineLoggerFnName[] = "SetImeEngineLogger";
 typedef void (*SetImeEngineLoggerFn)(ChromeLoggerFunc logger_func);
@@ -68,7 +69,8 @@
   virtual ~ImeDecoder() = default;
 
   // Function pointers to "C" API entry points of the loaded IME shared library.
-  // See ash/services/ime/public/cpp/shared_lib/interfaces.h for API specs.
+  // See chromeos/ash/services/ime/public/cpp/shared_lib/interfaces.h for API
+  // specs.
   struct EntryPoints {
     InitProtoModeFn init_proto_mode;
     CloseProtoModeFn close_proto_mode;
@@ -129,4 +131,4 @@
 }  // namespace ime
 }  // namespace ash
 
-#endif  // ASH_SERVICES_IME_IME_DECODER_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_IME_DECODER_H_
diff --git a/ash/services/ime/ime_sandbox_hook.cc b/chromeos/ash/services/ime/ime_sandbox_hook.cc
similarity index 95%
rename from ash/services/ime/ime_sandbox_hook.cc
rename to chromeos/ash/services/ime/ime_sandbox_hook.cc
index f2995a6..c64cff8 100644
--- a/ash/services/ime/ime_sandbox_hook.cc
+++ b/chromeos/ash/services/ime/ime_sandbox_hook.cc
@@ -2,16 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ash/services/ime/ime_sandbox_hook.h"
+#include "chromeos/ash/services/ime/ime_sandbox_hook.h"
 
 #include <dlfcn.h>
 #include <vector>
 
-#include "ash/services/ime/constants.h"
-#include "ash/services/ime/ime_decoder.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
+#include "chromeos/ash/services/ime/constants.h"
+#include "chromeos/ash/services/ime/ime_decoder.h"
 #include "sandbox/linux/syscall_broker/broker_command.h"
 #include "sandbox/linux/syscall_broker/broker_file_permission.h"
 
diff --git a/ash/services/ime/ime_sandbox_hook.h b/chromeos/ash/services/ime/ime_sandbox_hook.h
similarity index 67%
rename from ash/services/ime/ime_sandbox_hook.h
rename to chromeos/ash/services/ime/ime_sandbox_hook.h
index 9cb996de..bad9cf8f 100644
--- a/ash/services/ime/ime_sandbox_hook.h
+++ b/chromeos/ash/services/ime/ime_sandbox_hook.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 ASH_SERVICES_IME_IME_SANDBOX_HOOK_H_
-#define ASH_SERVICES_IME_IME_SANDBOX_HOOK_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_IME_SANDBOX_HOOK_H_
+#define CHROMEOS_ASH_SERVICES_IME_IME_SANDBOX_HOOK_H_
 
 #include "sandbox/policy/linux/sandbox_linux.h"
 
@@ -15,4 +15,4 @@
 }  // namespace ime
 }  // namespace ash
 
-#endif  // ASH_SERVICES_IME_IME_SANDBOX_HOOK_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_IME_SANDBOX_HOOK_H_
diff --git a/ash/services/ime/ime_service.cc b/chromeos/ash/services/ime/ime_service.cc
similarity index 96%
rename from ash/services/ime/ime_service.cc
rename to chromeos/ash/services/ime/ime_service.cc
index 1896c49..a374b76 100644
--- a/ash/services/ime/ime_service.cc
+++ b/chromeos/ash/services/ime/ime_service.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 "ash/services/ime/ime_service.h"
+#include "chromeos/ash/services/ime/ime_service.h"
 
 #include <memory>
 #include <string>
@@ -10,15 +10,15 @@
 #include <vector>
 
 #include "ash/constants/ash_features.h"
-#include "ash/services/ime/constants.h"
-#include "ash/services/ime/decoder/decoder_engine.h"
-#include "ash/services/ime/decoder/system_engine.h"
-#include "ash/services/ime/rule_based_engine.h"
 #include "base/bind.h"
 #include "base/files/file_util.h"
 #include "base/location.h"
 #include "base/notreached.h"
 #include "base/task/sequenced_task_runner.h"
+#include "chromeos/ash/services/ime/constants.h"
+#include "chromeos/ash/services/ime/decoder/decoder_engine.h"
+#include "chromeos/ash/services/ime/decoder/system_engine.h"
+#include "chromeos/ash/services/ime/rule_based_engine.h"
 #include "mojo/public/c/system/thunks.h"
 
 namespace ash {
diff --git a/ash/services/ime/ime_service.h b/chromeos/ash/services/ime/ime_service.h
similarity index 90%
rename from ash/services/ime/ime_service.h
rename to chromeos/ash/services/ime/ime_service.h
index 62706861..42bf0393 100644
--- a/ash/services/ime/ime_service.h
+++ b/chromeos/ash/services/ime/ime_service.h
@@ -2,23 +2,23 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ASH_SERVICES_IME_IME_SERVICE_H_
-#define ASH_SERVICES_IME_IME_SERVICE_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_IME_SERVICE_H_
+#define CHROMEOS_ASH_SERVICES_IME_IME_SERVICE_H_
 
 #include <memory>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "ash/services/ime/connection_factory.h"
-#include "ash/services/ime/decoder/decoder_engine.h"
-#include "ash/services/ime/decoder/system_engine.h"
-#include "ash/services/ime/public/cpp/shared_lib/interfaces.h"
-#include "ash/services/ime/public/mojom/ime_service.mojom.h"
-#include "ash/services/ime/rule_based_engine.h"
 #include "base/feature_list.h"
 #include "base/files/file_path.h"
 #include "base/metrics/field_trial_params.h"
+#include "chromeos/ash/services/ime/connection_factory.h"
+#include "chromeos/ash/services/ime/decoder/decoder_engine.h"
+#include "chromeos/ash/services/ime/decoder/system_engine.h"
+#include "chromeos/ash/services/ime/public/cpp/shared_lib/interfaces.h"
+#include "chromeos/ash/services/ime/public/mojom/ime_service.mojom.h"
+#include "chromeos/ash/services/ime/rule_based_engine.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/receiver.h"
@@ -143,4 +143,4 @@
 }  // namespace ime
 }  // namespace ash
 
-#endif  // ASH_SERVICES_IME_IME_SERVICE_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_IME_SERVICE_H_
diff --git a/ash/services/ime/ime_service_unittest.cc b/chromeos/ash/services/ime/ime_service_unittest.cc
similarity index 98%
rename from ash/services/ime/ime_service_unittest.cc
rename to chromeos/ash/services/ime/ime_service_unittest.cc
index b3b8cd77..bee39f3 100644
--- a/ash/services/ime/ime_service_unittest.cc
+++ b/chromeos/ash/services/ime/ime_service_unittest.cc
@@ -2,20 +2,20 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ash/services/ime/ime_service.h"
+#include "chromeos/ash/services/ime/ime_service.h"
 
 #include "ash/constants/ash_features.h"
-#include "ash/services/ime/ime_decoder.h"
-#include "ash/services/ime/mock_input_channel.h"
-#include "ash/services/ime/public/mojom/input_engine.mojom.h"
-#include "ash/services/ime/public/mojom/input_method.mojom.h"
-#include "ash/services/ime/public/mojom/input_method_host.mojom.h"
 #include "base/bind.h"
 #include "base/strings/strcat.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/bind.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
+#include "chromeos/ash/services/ime/ime_decoder.h"
+#include "chromeos/ash/services/ime/mock_input_channel.h"
+#include "chromeos/ash/services/ime/public/mojom/input_engine.mojom.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method.mojom.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method_host.mojom.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/receiver.h"
@@ -158,6 +158,7 @@
   void RecordUkm(mojom::UkmEntryPtr entry) override {}
   void ReportKoreanAction(mojom::KoreanAction action) override {}
   void ReportKoreanSettings(mojom::KoreanSettingsPtr settings) override {}
+  void ReportSuggestionOpportunity(TextSuggestionMode mode) override {}
   void UpdateQuickSettings(
       mojom::InputMethodQuickSettingsPtr settings) override {}
 
@@ -210,6 +211,7 @@
   void RecordUkm(mojom::UkmEntryPtr entry) override {}
   void ReportKoreanAction(mojom::KoreanAction action) override {}
   void ReportKoreanSettings(mojom::KoreanSettingsPtr settings) override {}
+  void ReportSuggestionOpportunity(TextSuggestionMode mode) override {}
   void UpdateQuickSettings(
       mojom::InputMethodQuickSettingsPtr settings) override {}
 
diff --git a/ash/services/ime/mock_input_channel.cc b/chromeos/ash/services/ime/mock_input_channel.cc
similarity index 92%
rename from ash/services/ime/mock_input_channel.cc
rename to chromeos/ash/services/ime/mock_input_channel.cc
index 022b2c4..91959aca 100644
--- a/ash/services/ime/mock_input_channel.cc
+++ b/chromeos/ash/services/ime/mock_input_channel.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 "ash/services/ime/mock_input_channel.h"
+#include "chromeos/ash/services/ime/mock_input_channel.h"
 
 namespace ash {
 namespace ime {
diff --git a/ash/services/ime/mock_input_channel.h b/chromeos/ash/services/ime/mock_input_channel.h
similarity index 71%
rename from ash/services/ime/mock_input_channel.h
rename to chromeos/ash/services/ime/mock_input_channel.h
index 205bd72c0..c8a0b4f5 100644
--- a/ash/services/ime/mock_input_channel.h
+++ b/chromeos/ash/services/ime/mock_input_channel.h
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ASH_SERVICES_IME_MOCK_INPUT_CHANNEL_H_
-#define ASH_SERVICES_IME_MOCK_INPUT_CHANNEL_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_MOCK_INPUT_CHANNEL_H_
+#define CHROMEOS_ASH_SERVICES_IME_MOCK_INPUT_CHANNEL_H_
 
-#include "ash/services/ime/public/mojom/input_engine.mojom.h"
-#include "ash/services/ime/public/mojom/input_method.mojom.h"
-#include "ash/services/ime/public/mojom/input_method_host.mojom.h"
+#include "chromeos/ash/services/ime/public/mojom/input_engine.mojom.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method.mojom.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method_host.mojom.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -38,4 +38,4 @@
 }  // namespace ime
 }  // namespace ash
 
-#endif  // ASH_SERVICES_IME_MOCK_INPUT_CHANNEL_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_MOCK_INPUT_CHANNEL_H_
diff --git a/ash/services/ime/public/cpp/BUILD.gn b/chromeos/ash/services/ime/public/cpp/BUILD.gn
similarity index 96%
rename from ash/services/ime/public/cpp/BUILD.gn
rename to chromeos/ash/services/ime/public/cpp/BUILD.gn
index 8d84679..58ab0df 100644
--- a/ash/services/ime/public/cpp/BUILD.gn
+++ b/chromeos/ash/services/ime/public/cpp/BUILD.gn
@@ -90,8 +90,8 @@
   ]
 
   deps = [
-    "//ash/services/ime/public/mojom:mojom",
     "//base",
+    "//chromeos/ash/services/ime/public/mojom:mojom",
     "//third_party/re2",
   ]
 }
@@ -100,8 +100,8 @@
   testonly = true
   deps = [
     ":rulebased",
-    "//ash/services/ime/public/mojom:mojom_shared_cpp_sources",
     "//base",
+    "//chromeos/ash/services/ime/public/mojom:mojom_shared_cpp_sources",
     "//testing/gmock",
     "//testing/gtest:gtest",
   ]
diff --git a/ash/services/ime/public/cpp/rulebased/def/ar.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/ar.cc
similarity index 99%
rename from ash/services/ime/public/cpp/rulebased/def/ar.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ar.cc
index d4c16e8e..5489db6 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ar.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ar.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 "ash/services/ime/public/cpp/rulebased/def/ar.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ar.h"
 
 namespace ar {
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/ar.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/ar.h
similarity index 67%
rename from ash/services/ime/public/cpp/rulebased/def/ar.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ar.h
index dc14fc7..2b3ad09 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ar.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ar.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_AR_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_AR_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_AR_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_AR_H_
 
 namespace ar {
 
@@ -18,4 +18,4 @@
 
 }  // namespace ar
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_AR_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_AR_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/bn_phone.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/bn_phone.cc
similarity index 99%
rename from ash/services/ime/public/cpp/rulebased/def/bn_phone.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/bn_phone.cc
index 4b4acdcd..ca74d6d7 100644
--- a/ash/services/ime/public/cpp/rulebased/def/bn_phone.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/bn_phone.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 "ash/services/ime/public/cpp/rulebased/def/bn_phone.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/bn_phone.h"
 
 #include <iterator>
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/bn_phone.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/bn_phone.h
similarity index 79%
rename from ash/services/ime/public/cpp/rulebased/def/bn_phone.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/bn_phone.h
index 3a695b1..2d16b4a 100644
--- a/ash/services/ime/public/cpp/rulebased/def/bn_phone.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/bn_phone.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_BN_PHONE_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_BN_PHONE_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_BN_PHONE_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_BN_PHONE_H_
 
 namespace bn_phone {
 
@@ -29,4 +29,4 @@
 
 }  // namespace bn_phone
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_BN_PHONE_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_BN_PHONE_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/ckb_ar.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/ckb_ar.cc
similarity index 97%
rename from ash/services/ime/public/cpp/rulebased/def/ckb_ar.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ckb_ar.cc
index 61e3bd9..e9ee462 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ckb_ar.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ckb_ar.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 "ash/services/ime/public/cpp/rulebased/def/ckb_ar.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ckb_ar.h"
 
 namespace ckb_ar {
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/ckb_ar.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/ckb_ar.h
similarity index 66%
rename from ash/services/ime/public/cpp/rulebased/def/ckb_ar.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ckb_ar.h
index 7393de99..3f48852 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ckb_ar.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ckb_ar.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_CKB_AR_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_CKB_AR_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_CKB_AR_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_CKB_AR_H_
 
 namespace ckb_ar {
 
@@ -18,4 +18,4 @@
 
 }  // namespace ckb_ar
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_CKB_AR_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_CKB_AR_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/ckb_en.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/ckb_en.cc
similarity index 97%
rename from ash/services/ime/public/cpp/rulebased/def/ckb_en.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ckb_en.cc
index ecce7c8..8e835db 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ckb_en.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ckb_en.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 "ash/services/ime/public/cpp/rulebased/def/ckb_en.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ckb_en.h"
 
 namespace ckb_en {
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/ckb_en.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/ckb_en.h
similarity index 66%
rename from ash/services/ime/public/cpp/rulebased/def/ckb_en.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ckb_en.h
index 1c0e986..ae90eee9 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ckb_en.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ckb_en.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_CKB_EN_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_CKB_EN_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_CKB_EN_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_CKB_EN_H_
 
 namespace ckb_en {
 
@@ -18,4 +18,4 @@
 
 }  // namespace ckb_en
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_CKB_EN_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_CKB_EN_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/deva_phone.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/deva_phone.cc
similarity index 99%
rename from ash/services/ime/public/cpp/rulebased/def/deva_phone.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/deva_phone.cc
index 421df65..cbe36cf5 100644
--- a/ash/services/ime/public/cpp/rulebased/def/deva_phone.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/deva_phone.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 "ash/services/ime/public/cpp/rulebased/def/deva_phone.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/deva_phone.h"
 
 #include <iterator>
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/deva_phone.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/deva_phone.h
similarity index 74%
rename from ash/services/ime/public/cpp/rulebased/def/deva_phone.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/deva_phone.h
index dffc3e3b..3e46796 100644
--- a/ash/services/ime/public/cpp/rulebased/def/deva_phone.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/deva_phone.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_DEVA_PHONE_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_DEVA_PHONE_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_DEVA_PHONE_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_DEVA_PHONE_H_
 
 namespace deva_phone {
 
@@ -23,4 +23,4 @@
 
 }  // namespace deva_phone
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_DEVA_PHONE_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_DEVA_PHONE_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/ethi.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/ethi.cc
similarity index 99%
rename from ash/services/ime/public/cpp/rulebased/def/ethi.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ethi.cc
index c6b73af8..66524b1f 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ethi.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ethi.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 "ash/services/ime/public/cpp/rulebased/def/ethi.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ethi.h"
 
 #include <iterator>
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/ethi.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/ethi.h
similarity index 79%
rename from ash/services/ime/public/cpp/rulebased/def/ethi.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ethi.h
index 4734349..1285974 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ethi.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ethi.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_ETHI_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_ETHI_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_ETHI_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_ETHI_H_
 
 namespace ethi {
 
@@ -29,4 +29,4 @@
 
 }  // namespace ethi
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_ETHI_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_ETHI_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/fa.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/fa.cc
similarity index 98%
rename from ash/services/ime/public/cpp/rulebased/def/fa.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/fa.cc
index bd3905b..3478568 100644
--- a/ash/services/ime/public/cpp/rulebased/def/fa.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/fa.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 "ash/services/ime/public/cpp/rulebased/def/fa.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/fa.h"
 
 namespace fa {
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/fa.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/fa.h
similarity index 67%
rename from ash/services/ime/public/cpp/rulebased/def/fa.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/fa.h
index 65be1b08..1251cbf 100644
--- a/ash/services/ime/public/cpp/rulebased/def/fa.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/fa.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_FA_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_FA_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_FA_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_FA_H_
 
 namespace fa {
 
@@ -18,4 +18,4 @@
 
 }  // namespace fa
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_FA_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_FA_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/gu_phone.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/gu_phone.cc
similarity index 99%
rename from ash/services/ime/public/cpp/rulebased/def/gu_phone.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/gu_phone.cc
index 80ad1696..0f2cdff 100644
--- a/ash/services/ime/public/cpp/rulebased/def/gu_phone.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/gu_phone.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 "ash/services/ime/public/cpp/rulebased/def/gu_phone.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/gu_phone.h"
 
 #include <iterator>
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/gu_phone.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/gu_phone.h
similarity index 79%
rename from ash/services/ime/public/cpp/rulebased/def/gu_phone.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/gu_phone.h
index b3b90bc..37ac6da 100644
--- a/ash/services/ime/public/cpp/rulebased/def/gu_phone.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/gu_phone.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_GU_PHONE_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_GU_PHONE_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_GU_PHONE_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_GU_PHONE_H_
 
 namespace gu_phone {
 
@@ -29,4 +29,4 @@
 
 }  // namespace gu_phone
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_GU_PHONE_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_GU_PHONE_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/hi_inscript.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/hi_inscript.cc
similarity index 98%
rename from ash/services/ime/public/cpp/rulebased/def/hi_inscript.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/hi_inscript.cc
index 59d827e6..fd22077 100644
--- a/ash/services/ime/public/cpp/rulebased/def/hi_inscript.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/hi_inscript.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 "ash/services/ime/public/cpp/rulebased/def/hi_inscript.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/hi_inscript.h"
 
 namespace hi_inscript {
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/hi_inscript.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/hi_inscript.h
similarity index 66%
rename from ash/services/ime/public/cpp/rulebased/def/hi_inscript.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/hi_inscript.h
index b883492..aa13de3 100644
--- a/ash/services/ime/public/cpp/rulebased/def/hi_inscript.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/hi_inscript.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_HI_INSCRIPT_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_HI_INSCRIPT_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_HI_INSCRIPT_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_HI_INSCRIPT_H_
 
 namespace hi_inscript {
 
@@ -18,4 +18,4 @@
 
 }  // namespace hi_inscript
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_HI_INSCRIPT_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_HI_INSCRIPT_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/km.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/km.cc
similarity index 99%
rename from ash/services/ime/public/cpp/rulebased/def/km.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/km.cc
index 766240f..f90e0f09 100644
--- a/ash/services/ime/public/cpp/rulebased/def/km.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/km.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 "ash/services/ime/public/cpp/rulebased/def/km.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/km.h"
 
 namespace km {
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/km.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/km.h
similarity index 67%
rename from ash/services/ime/public/cpp/rulebased/def/km.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/km.h
index b8b9a03a..6dade02 100644
--- a/ash/services/ime/public/cpp/rulebased/def/km.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/km.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_KM_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_KM_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_KM_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_KM_H_
 
 namespace km {
 
@@ -18,4 +18,4 @@
 
 }  // namespace km
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_KM_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_KM_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/kn_phone.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/kn_phone.cc
similarity index 99%
rename from ash/services/ime/public/cpp/rulebased/def/kn_phone.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/kn_phone.cc
index 479e438e..9ddad42 100644
--- a/ash/services/ime/public/cpp/rulebased/def/kn_phone.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/kn_phone.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 "ash/services/ime/public/cpp/rulebased/def/kn_phone.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/kn_phone.h"
 
 #include <iterator>
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/kn_phone.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/kn_phone.h
similarity index 74%
rename from ash/services/ime/public/cpp/rulebased/def/kn_phone.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/kn_phone.h
index 266707ef8..ab9e1f8 100644
--- a/ash/services/ime/public/cpp/rulebased/def/kn_phone.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/kn_phone.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_KN_PHONE_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_KN_PHONE_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_KN_PHONE_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_KN_PHONE_H_
 
 namespace kn_phone {
 
@@ -23,4 +23,4 @@
 
 }  // namespace kn_phone
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_KN_PHONE_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_KN_PHONE_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/lo.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/lo.cc
similarity index 98%
rename from ash/services/ime/public/cpp/rulebased/def/lo.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/lo.cc
index 59dbfc5..74a909b 100644
--- a/ash/services/ime/public/cpp/rulebased/def/lo.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/lo.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 "ash/services/ime/public/cpp/rulebased/def/lo.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/lo.h"
 
 namespace lo {
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/lo.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/lo.h
similarity index 67%
rename from ash/services/ime/public/cpp/rulebased/def/lo.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/lo.h
index 872f2971..eee15b1 100644
--- a/ash/services/ime/public/cpp/rulebased/def/lo.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/lo.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_LO_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_LO_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_LO_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_LO_H_
 
 namespace lo {
 
@@ -18,4 +18,4 @@
 
 }  // namespace lo
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_LO_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_LO_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/ml_phone.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/ml_phone.cc
similarity index 99%
rename from ash/services/ime/public/cpp/rulebased/def/ml_phone.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ml_phone.cc
index f072348b..c9f9981 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ml_phone.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ml_phone.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 "ash/services/ime/public/cpp/rulebased/def/ml_phone.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ml_phone.h"
 
 #include <iterator>
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/ml_phone.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/ml_phone.h
similarity index 74%
rename from ash/services/ime/public/cpp/rulebased/def/ml_phone.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ml_phone.h
index 6a018ca9..eba8944d 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ml_phone.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ml_phone.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_ML_PHONE_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_ML_PHONE_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_ML_PHONE_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_ML_PHONE_H_
 
 namespace ml_phone {
 
@@ -23,4 +23,4 @@
 
 }  // namespace ml_phone
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_ML_PHONE_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_ML_PHONE_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/my.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/my.cc
similarity index 99%
rename from ash/services/ime/public/cpp/rulebased/def/my.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/my.cc
index baf2d3f..6823f776 100644
--- a/ash/services/ime/public/cpp/rulebased/def/my.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/my.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 "ash/services/ime/public/cpp/rulebased/def/my.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/my.h"
 
 #include <iterator>
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/my.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/my.h
similarity index 80%
rename from ash/services/ime/public/cpp/rulebased/def/my.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/my.h
index 5cb21b6..104e0858 100644
--- a/ash/services/ime/public/cpp/rulebased/def/my.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/my.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_MY_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_MY_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_MY_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_MY_H_
 
 namespace my {
 
@@ -29,4 +29,4 @@
 
 }  // namespace my
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_MY_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_MY_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/my_myansan.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/my_myansan.cc
similarity index 99%
rename from ash/services/ime/public/cpp/rulebased/def/my_myansan.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/my_myansan.cc
index 176e0ab..d5dd343 100644
--- a/ash/services/ime/public/cpp/rulebased/def/my_myansan.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/my_myansan.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 "ash/services/ime/public/cpp/rulebased/def/my_myansan.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/my_myansan.h"
 
 #include <iterator>
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/my_myansan.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/my_myansan.h
similarity index 78%
rename from ash/services/ime/public/cpp/rulebased/def/my_myansan.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/my_myansan.h
index 64cf7d5d..5cce6836 100644
--- a/ash/services/ime/public/cpp/rulebased/def/my_myansan.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/my_myansan.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_MY_MYANSAN_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_MY_MYANSAN_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_MY_MYANSAN_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_MY_MYANSAN_H_
 
 namespace my_myansan {
 
@@ -29,4 +29,4 @@
 
 }  // namespace my_myansan
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_MY_MYANSAN_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_MY_MYANSAN_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/ne_inscript.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/ne_inscript.cc
similarity index 98%
rename from ash/services/ime/public/cpp/rulebased/def/ne_inscript.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ne_inscript.cc
index 177f257..c70ab6e 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ne_inscript.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ne_inscript.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 "ash/services/ime/public/cpp/rulebased/def/ne_inscript.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ne_inscript.h"
 
 namespace ne_inscript {
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/ne_inscript.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/ne_inscript.h
similarity index 65%
rename from ash/services/ime/public/cpp/rulebased/def/ne_inscript.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ne_inscript.h
index bd8c1ff..35ea7e3 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ne_inscript.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ne_inscript.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_NE_INSCRIPT_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_NE_INSCRIPT_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_NE_INSCRIPT_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_NE_INSCRIPT_H_
 
 namespace ne_inscript {
 
@@ -18,4 +18,4 @@
 
 }  // namespace ne_inscript
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_NE_INSCRIPT_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_NE_INSCRIPT_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/ne_phone.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/ne_phone.cc
similarity index 98%
rename from ash/services/ime/public/cpp/rulebased/def/ne_phone.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ne_phone.cc
index a1d75698da..9cf0dfcd 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ne_phone.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ne_phone.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 "ash/services/ime/public/cpp/rulebased/def/ne_phone.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ne_phone.h"
 
 namespace ne_phone {
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/ne_phone.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/ne_phone.h
similarity index 66%
rename from ash/services/ime/public/cpp/rulebased/def/ne_phone.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ne_phone.h
index 6621f73..45ed77b 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ne_phone.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ne_phone.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_NE_PHONE_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_NE_PHONE_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_NE_PHONE_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_NE_PHONE_H_
 
 namespace ne_phone {
 
@@ -18,4 +18,4 @@
 
 }  // namespace ne_phone
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_NE_PHONE_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_NE_PHONE_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/ru_phone_aatseel.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/ru_phone_aatseel.cc
similarity index 98%
rename from ash/services/ime/public/cpp/rulebased/def/ru_phone_aatseel.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ru_phone_aatseel.cc
index 4a3827dc..464dd61 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ru_phone_aatseel.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ru_phone_aatseel.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 "ash/services/ime/public/cpp/rulebased/def/ru_phone_aatseel.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ru_phone_aatseel.h"
 
 namespace ru_phone_aatseel {
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/ru_phone_aatseel.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/ru_phone_aatseel.h
similarity index 64%
rename from ash/services/ime/public/cpp/rulebased/def/ru_phone_aatseel.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ru_phone_aatseel.h
index c52c64ea..a85d41ec 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ru_phone_aatseel.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ru_phone_aatseel.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_RU_PHONE_AATSEEL_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_RU_PHONE_AATSEEL_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_RU_PHONE_AATSEEL_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_RU_PHONE_AATSEEL_H_
 
 namespace ru_phone_aatseel {
 
@@ -18,4 +18,4 @@
 
 }  // namespace ru_phone_aatseel
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_RU_PHONE_AATSEEL_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_RU_PHONE_AATSEEL_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/ru_phone_yazhert.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/ru_phone_yazhert.cc
similarity index 98%
rename from ash/services/ime/public/cpp/rulebased/def/ru_phone_yazhert.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ru_phone_yazhert.cc
index 9ad7acf..a49fb41 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ru_phone_yazhert.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ru_phone_yazhert.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 "ash/services/ime/public/cpp/rulebased/def/ru_phone_yazhert.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ru_phone_yazhert.h"
 
 namespace ru_phone_yazhert {
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/ru_phone_yazhert.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/ru_phone_yazhert.h
similarity index 64%
rename from ash/services/ime/public/cpp/rulebased/def/ru_phone_yazhert.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ru_phone_yazhert.h
index caaaca0a..be87a7e 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ru_phone_yazhert.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ru_phone_yazhert.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_RU_PHONE_YAZHERT_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_RU_PHONE_YAZHERT_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_RU_PHONE_YAZHERT_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_RU_PHONE_YAZHERT_H_
 
 namespace ru_phone_yazhert {
 
@@ -18,4 +18,4 @@
 
 }  // namespace ru_phone_yazhert
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_RU_PHONE_YAZHERT_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_RU_PHONE_YAZHERT_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/si.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/si.cc
similarity index 99%
rename from ash/services/ime/public/cpp/rulebased/def/si.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/si.cc
index be1dca44..c8125e4b 100644
--- a/ash/services/ime/public/cpp/rulebased/def/si.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/si.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 "ash/services/ime/public/cpp/rulebased/def/si.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/si.h"
 
 #include <iterator>
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/si.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/si.h
similarity index 80%
rename from ash/services/ime/public/cpp/rulebased/def/si.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/si.h
index 5d5b0ea7..d232c96e 100644
--- a/ash/services/ime/public/cpp/rulebased/def/si.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/si.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_SI_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_SI_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_SI_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_SI_H_
 
 namespace si {
 
@@ -29,4 +29,4 @@
 
 }  // namespace si
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_SI_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_SI_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/ta_inscript.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/ta_inscript.cc
similarity index 98%
rename from ash/services/ime/public/cpp/rulebased/def/ta_inscript.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ta_inscript.cc
index b9e64e9..c86655d 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ta_inscript.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ta_inscript.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 "ash/services/ime/public/cpp/rulebased/def/ta_inscript.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ta_inscript.h"
 
 namespace ta_inscript {
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/ta_inscript.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/ta_inscript.h
similarity index 65%
rename from ash/services/ime/public/cpp/rulebased/def/ta_inscript.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ta_inscript.h
index 8129ad8..a4595da 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ta_inscript.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ta_inscript.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_INSCRIPT_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_INSCRIPT_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_INSCRIPT_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_INSCRIPT_H_
 
 namespace ta_inscript {
 
@@ -18,4 +18,4 @@
 
 }  // namespace ta_inscript
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_INSCRIPT_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_INSCRIPT_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/ta_itrans.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/ta_itrans.cc
similarity index 97%
rename from ash/services/ime/public/cpp/rulebased/def/ta_itrans.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ta_itrans.cc
index 4695c242..e7ea3e1 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ta_itrans.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ta_itrans.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 "ash/services/ime/public/cpp/rulebased/def/ta_itrans.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ta_itrans.h"
 
 #include <iterator>
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/ta_itrans.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/ta_itrans.h
similarity index 74%
rename from ash/services/ime/public/cpp/rulebased/def/ta_itrans.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ta_itrans.h
index 73fe986..fb82282 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ta_itrans.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ta_itrans.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_ITRANS_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_ITRANS_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_ITRANS_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_ITRANS_H_
 
 namespace ta_itrans {
 
@@ -23,4 +23,4 @@
 
 }  // namespace ta_itrans
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_ITRANS_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_ITRANS_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/ta_phone.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/ta_phone.cc
similarity index 99%
rename from ash/services/ime/public/cpp/rulebased/def/ta_phone.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ta_phone.cc
index 9920e77c..4d77e2d 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ta_phone.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ta_phone.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 "ash/services/ime/public/cpp/rulebased/def/ta_phone.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ta_phone.h"
 
 #include <iterator>
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/ta_phone.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/ta_phone.h
similarity index 79%
rename from ash/services/ime/public/cpp/rulebased/def/ta_phone.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ta_phone.h
index 3933a74..6ea1393 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ta_phone.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ta_phone.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_PHONE_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_PHONE_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_PHONE_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_PHONE_H_
 
 namespace ta_phone {
 
@@ -29,4 +29,4 @@
 
 }  // namespace ta_phone
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_PHONE_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_PHONE_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/ta_tamil99.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/ta_tamil99.cc
similarity index 99%
rename from ash/services/ime/public/cpp/rulebased/def/ta_tamil99.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ta_tamil99.cc
index 46a8d3bc..121eebd 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ta_tamil99.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ta_tamil99.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 "ash/services/ime/public/cpp/rulebased/def/ta_tamil99.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ta_tamil99.h"
 
 #include <iterator>
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/ta_tamil99.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/ta_tamil99.h
similarity index 78%
rename from ash/services/ime/public/cpp/rulebased/def/ta_tamil99.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ta_tamil99.h
index bcba96f..d012ce3 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ta_tamil99.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ta_tamil99.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_TAMIL99_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_TAMIL99_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_TAMIL99_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_TAMIL99_H_
 
 namespace ta_tamil99 {
 
@@ -29,4 +29,4 @@
 
 }  // namespace ta_tamil99
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_TAMIL99_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_TAMIL99_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/ta_typewriter.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/ta_typewriter.cc
similarity index 98%
rename from ash/services/ime/public/cpp/rulebased/def/ta_typewriter.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ta_typewriter.cc
index 7b6b18486..05bfb9b8 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ta_typewriter.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ta_typewriter.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 "ash/services/ime/public/cpp/rulebased/def/ta_typewriter.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ta_typewriter.h"
 
 namespace ta_typewriter {
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/ta_typewriter.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/ta_typewriter.h
similarity index 65%
rename from ash/services/ime/public/cpp/rulebased/def/ta_typewriter.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/ta_typewriter.h
index 0b4c11cb..1c55832 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ta_typewriter.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/ta_typewriter.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_TYPEWRITER_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_TYPEWRITER_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_TYPEWRITER_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_TYPEWRITER_H_
 
 namespace ta_typewriter {
 
@@ -18,4 +18,4 @@
 
 }  // namespace ta_typewriter
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_TYPEWRITER_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TA_TYPEWRITER_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/te_phone.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/te_phone.cc
similarity index 99%
rename from ash/services/ime/public/cpp/rulebased/def/te_phone.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/te_phone.cc
index 9b322fc..86815fe 100644
--- a/ash/services/ime/public/cpp/rulebased/def/te_phone.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/te_phone.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 "ash/services/ime/public/cpp/rulebased/def/te_phone.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/te_phone.h"
 
 #include <iterator>
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/te_phone.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/te_phone.h
similarity index 74%
rename from ash/services/ime/public/cpp/rulebased/def/te_phone.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/te_phone.h
index cc3815e..87eddb16 100644
--- a/ash/services/ime/public/cpp/rulebased/def/te_phone.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/te_phone.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TE_PHONE_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TE_PHONE_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TE_PHONE_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TE_PHONE_H_
 
 namespace te_phone {
 
@@ -23,4 +23,4 @@
 
 }  // namespace te_phone
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TE_PHONE_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TE_PHONE_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/th.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/th.cc
similarity index 98%
rename from ash/services/ime/public/cpp/rulebased/def/th.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/th.cc
index bf6f6f79..2f1d2e6 100644
--- a/ash/services/ime/public/cpp/rulebased/def/th.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/th.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 "ash/services/ime/public/cpp/rulebased/def/th.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/th.h"
 
 namespace th {
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/th.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/th.h
similarity index 67%
rename from ash/services/ime/public/cpp/rulebased/def/th.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/th.h
index 9ac99242..573e6f4 100644
--- a/ash/services/ime/public/cpp/rulebased/def/th.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/th.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TH_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TH_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TH_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TH_H_
 
 namespace th {
 
@@ -18,4 +18,4 @@
 
 }  // namespace th
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TH_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TH_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/th_pattajoti.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/th_pattajoti.cc
similarity index 99%
rename from ash/services/ime/public/cpp/rulebased/def/th_pattajoti.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/th_pattajoti.cc
index 2691946..6a881a3 100644
--- a/ash/services/ime/public/cpp/rulebased/def/th_pattajoti.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/th_pattajoti.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 "ash/services/ime/public/cpp/rulebased/def/th_pattajoti.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/th_pattajoti.h"
 
 namespace th_pattajoti {
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/th_pattajoti.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/th_pattajoti.h
similarity index 65%
rename from ash/services/ime/public/cpp/rulebased/def/th_pattajoti.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/th_pattajoti.h
index a7ac194..684df1b 100644
--- a/ash/services/ime/public/cpp/rulebased/def/th_pattajoti.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/th_pattajoti.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TH_PATTAJOTI_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TH_PATTAJOTI_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TH_PATTAJOTI_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TH_PATTAJOTI_H_
 
 namespace th_pattajoti {
 
@@ -18,4 +18,4 @@
 
 }  // namespace th_pattajoti
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TH_PATTAJOTI_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TH_PATTAJOTI_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/th_tis.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/th_tis.cc
similarity index 98%
rename from ash/services/ime/public/cpp/rulebased/def/th_tis.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/th_tis.cc
index 6433ffc..b00d544e 100644
--- a/ash/services/ime/public/cpp/rulebased/def/th_tis.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/th_tis.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 "ash/services/ime/public/cpp/rulebased/def/th_tis.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/th_tis.h"
 
 namespace th_tis {
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/th_tis.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/th_tis.h
similarity index 66%
rename from ash/services/ime/public/cpp/rulebased/def/th_tis.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/th_tis.h
index f20e943..c4b9a1b 100644
--- a/ash/services/ime/public/cpp/rulebased/def/th_tis.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/th_tis.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TH_TIS_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TH_TIS_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TH_TIS_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TH_TIS_H_
 
 namespace th_tis {
 
@@ -18,4 +18,4 @@
 
 }  // namespace th_tis
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TH_TIS_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_TH_TIS_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/us.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/us.cc
similarity index 98%
rename from ash/services/ime/public/cpp/rulebased/def/us.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/us.cc
index 873b5d69..936e95b0 100644
--- a/ash/services/ime/public/cpp/rulebased/def/us.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/us.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 "ash/services/ime/public/cpp/rulebased/def/us.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/us.h"
 
 namespace us {
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/us.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/us.h
similarity index 68%
rename from ash/services/ime/public/cpp/rulebased/def/us.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/us.h
index 4ef6442..e903537e 100644
--- a/ash/services/ime/public/cpp/rulebased/def/us.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/us.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_US_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_US_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_US_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_US_H_
 
 namespace us {
 
@@ -18,4 +18,4 @@
 
 }  // namespace us
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_US_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_US_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/vi_tcvn.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/vi_tcvn.cc
similarity index 99%
rename from ash/services/ime/public/cpp/rulebased/def/vi_tcvn.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/vi_tcvn.cc
index 3036cc7..0f26525 100644
--- a/ash/services/ime/public/cpp/rulebased/def/vi_tcvn.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/vi_tcvn.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 "ash/services/ime/public/cpp/rulebased/def/vi_tcvn.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/vi_tcvn.h"
 
 #include <iterator>
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/vi_tcvn.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/vi_tcvn.h
similarity index 75%
rename from ash/services/ime/public/cpp/rulebased/def/vi_tcvn.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/vi_tcvn.h
index 93d39ca..ffbb406b 100644
--- a/ash/services/ime/public/cpp/rulebased/def/vi_tcvn.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/vi_tcvn.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_VI_TCVN_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_VI_TCVN_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_VI_TCVN_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_VI_TCVN_H_
 
 namespace vi_tcvn {
 
@@ -23,4 +23,4 @@
 
 }  // namespace vi_tcvn
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_VI_TCVN_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_VI_TCVN_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/vi_telex.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/vi_telex.cc
similarity index 97%
rename from ash/services/ime/public/cpp/rulebased/def/vi_telex.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/vi_telex.cc
index daf8ac3..bc7ad3c 100644
--- a/ash/services/ime/public/cpp/rulebased/def/vi_telex.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/vi_telex.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 "ash/services/ime/public/cpp/rulebased/def/vi_telex.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/vi_telex.h"
 
 #include <iterator>
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/vi_telex.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/vi_telex.h
similarity index 74%
rename from ash/services/ime/public/cpp/rulebased/def/vi_telex.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/vi_telex.h
index 00a2bdf..7decb20 100644
--- a/ash/services/ime/public/cpp/rulebased/def/vi_telex.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/vi_telex.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_VI_TELEX_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_VI_TELEX_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_VI_TELEX_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_VI_TELEX_H_
 
 namespace vi_telex {
 
@@ -23,4 +23,4 @@
 
 }  // namespace vi_telex
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_VI_TELEX_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_VI_TELEX_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/vi_viqr.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/vi_viqr.cc
similarity index 93%
rename from ash/services/ime/public/cpp/rulebased/def/vi_viqr.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/vi_viqr.cc
index 92233d9..f8061e8 100644
--- a/ash/services/ime/public/cpp/rulebased/def/vi_viqr.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/vi_viqr.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 "ash/services/ime/public/cpp/rulebased/def/vi_viqr.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/vi_viqr.h"
 
 #include <iterator>
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/vi_viqr.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/vi_viqr.h
similarity index 75%
rename from ash/services/ime/public/cpp/rulebased/def/vi_viqr.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/vi_viqr.h
index e7d7ccf..a23014c7 100644
--- a/ash/services/ime/public/cpp/rulebased/def/vi_viqr.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/vi_viqr.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_VI_VIQR_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_VI_VIQR_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_VI_VIQR_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_VI_VIQR_H_
 
 namespace vi_viqr {
 
@@ -23,4 +23,4 @@
 
 }  // namespace vi_viqr
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_VI_VIQR_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_VI_VIQR_H_
diff --git a/ash/services/ime/public/cpp/rulebased/def/vi_vni.cc b/chromeos/ash/services/ime/public/cpp/rulebased/def/vi_vni.cc
similarity index 97%
rename from ash/services/ime/public/cpp/rulebased/def/vi_vni.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/vi_vni.cc
index 7527d85..262b206f 100644
--- a/ash/services/ime/public/cpp/rulebased/def/vi_vni.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/vi_vni.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 "ash/services/ime/public/cpp/rulebased/def/vi_vni.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/vi_vni.h"
 
 #include <iterator>
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/vi_vni.h b/chromeos/ash/services/ime/public/cpp/rulebased/def/vi_vni.h
similarity index 75%
rename from ash/services/ime/public/cpp/rulebased/def/vi_vni.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/def/vi_vni.h
index 258aea3..7ba204da 100644
--- a/ash/services/ime/public/cpp/rulebased/def/vi_vni.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/def/vi_vni.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_VI_VNI_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_VI_VNI_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_VI_VNI_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_VI_VNI_H_
 
 namespace vi_vni {
 
@@ -23,4 +23,4 @@
 
 }  // namespace vi_vni
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_VI_VNI_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_DEF_VI_VNI_H_
diff --git a/ash/services/ime/public/cpp/rulebased/engine.cc b/chromeos/ash/services/ime/public/cpp/rulebased/engine.cc
similarity index 96%
rename from ash/services/ime/public/cpp/rulebased/engine.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/engine.cc
index be027bb..39608d6 100644
--- a/ash/services/ime/public/cpp/rulebased/engine.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/engine.cc
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ash/services/ime/public/cpp/rulebased/engine.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/engine.h"
 
-#include "ash/services/ime/public/cpp/rulebased/rules_data.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/rules_data.h"
 
 namespace ash {
 namespace ime {
diff --git a/ash/services/ime/public/cpp/rulebased/engine.h b/chromeos/ash/services/ime/public/cpp/rulebased/engine.h
similarity index 85%
rename from ash/services/ime/public/cpp/rulebased/engine.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/engine.h
index ffaeda0..5ba0456 100644
--- a/ash/services/ime/public/cpp/rulebased/engine.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/engine.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 ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_ENGINE_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_ENGINE_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_ENGINE_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_ENGINE_H_
 
 #include <memory>
 #include <string>
 
-#include "ash/services/ime/public/mojom/input_method.mojom.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method.mojom.h"
 
 namespace ash {
 namespace ime {
@@ -71,4 +71,4 @@
 }  // namespace ime
 }  // namespace ash
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_ENGINE_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_ENGINE_H_
diff --git a/ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.cc b/chromeos/ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.cc
similarity index 87%
rename from ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.cc
index 2df368085..768d70a4 100644
--- a/ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.cc
@@ -5,10 +5,10 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "ash/services/ime/public/cpp/rulebased/def/us.h"
-#include "ash/services/ime/public/cpp/rulebased/engine.h"
-#include "ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.pb.h"
-#include "ash/services/ime/public/cpp/rulebased/rules_data.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/us.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/engine.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.pb.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/rules_data.h"
 #include "testing/libfuzzer/proto/lpm_interface.h"
 
 namespace rulebased = ::ash::ime::rulebased;
@@ -16,7 +16,8 @@
 
 namespace {
 
-// Must match ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.proto
+// Must match
+// chromeos/ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.proto
 constexpr mojom::DomCode kKeyCodes[] = {
     mojom::DomCode::kBackquote,     mojom::DomCode::kDigit1,
     mojom::DomCode::kDigit2,        mojom::DomCode::kDigit3,
@@ -45,7 +46,8 @@
     mojom::DomCode::kPeriod,        mojom::DomCode::kSlash,
     mojom::DomCode::kSpace};
 
-// Must match ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.proto
+// Must match
+// chromeos/ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.proto
 constexpr const char* kEngineIds[] = {
     "ar",
     "bn_phone",
diff --git a/ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.proto b/chromeos/ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.proto
similarity index 92%
rename from ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.proto
rename to chromeos/ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.proto
index 092bfed..1b5128c 100644
--- a/ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.proto
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.proto
@@ -3,7 +3,7 @@
 package rulebased_fuzzer;
 
 // If you change this enum, please update the corresponding array in
-// //ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.cc
+// //chromeos/ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.cc
 enum KeyCode {
   BACKQUOTE = 0;
   DIGIT1 = 1;
@@ -59,7 +59,7 @@
 }
 
 // If you change this enum, please update the corresponding array in
-// //ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.cc
+// //chromeos/ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.cc
 enum EngineId {
   AR = 0;
   BN_PHONE = 1;
diff --git a/ash/services/ime/public/cpp/rulebased/rulebased_unittest.cc b/chromeos/ash/services/ime/public/cpp/rulebased/rulebased_unittest.cc
similarity index 96%
rename from ash/services/ime/public/cpp/rulebased/rulebased_unittest.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/rulebased_unittest.cc
index 07b4aac..ca5e6b7 100644
--- a/ash/services/ime/public/cpp/rulebased/rulebased_unittest.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/rulebased_unittest.cc
@@ -4,10 +4,10 @@
 
 #include <memory>
 
-#include "ash/services/ime/public/cpp/rulebased/def/us.h"
-#include "ash/services/ime/public/cpp/rulebased/engine.h"
-#include "ash/services/ime/public/cpp/rulebased/rules_data.h"
-#include "ash/services/ime/public/mojom/input_method.mojom-shared.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/us.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/engine.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/rules_data.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method.mojom-shared.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace ash {
diff --git a/ash/services/ime/public/cpp/rulebased/rules_data.cc b/chromeos/ash/services/ime/public/cpp/rulebased/rules_data.cc
similarity index 86%
rename from ash/services/ime/public/cpp/rulebased/rules_data.cc
rename to chromeos/ash/services/ime/public/cpp/rulebased/rules_data.cc
index 981c757..d0bd206 100644
--- a/ash/services/ime/public/cpp/rulebased/rules_data.cc
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/rules_data.cc
@@ -2,45 +2,45 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ash/services/ime/public/cpp/rulebased/rules_data.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/rules_data.h"
 
-#include "ash/services/ime/public/cpp/rulebased/def/ar.h"
-#include "ash/services/ime/public/cpp/rulebased/def/bn_phone.h"
-#include "ash/services/ime/public/cpp/rulebased/def/ckb_ar.h"
-#include "ash/services/ime/public/cpp/rulebased/def/ckb_en.h"
-#include "ash/services/ime/public/cpp/rulebased/def/deva_phone.h"
-#include "ash/services/ime/public/cpp/rulebased/def/ethi.h"
-#include "ash/services/ime/public/cpp/rulebased/def/fa.h"
-#include "ash/services/ime/public/cpp/rulebased/def/gu_phone.h"
-#include "ash/services/ime/public/cpp/rulebased/def/hi_inscript.h"
-#include "ash/services/ime/public/cpp/rulebased/def/km.h"
-#include "ash/services/ime/public/cpp/rulebased/def/kn_phone.h"
-#include "ash/services/ime/public/cpp/rulebased/def/lo.h"
-#include "ash/services/ime/public/cpp/rulebased/def/ml_phone.h"
-#include "ash/services/ime/public/cpp/rulebased/def/my.h"
-#include "ash/services/ime/public/cpp/rulebased/def/my_myansan.h"
-#include "ash/services/ime/public/cpp/rulebased/def/ne_inscript.h"
-#include "ash/services/ime/public/cpp/rulebased/def/ne_phone.h"
-#include "ash/services/ime/public/cpp/rulebased/def/ru_phone_aatseel.h"
-#include "ash/services/ime/public/cpp/rulebased/def/ru_phone_yazhert.h"
-#include "ash/services/ime/public/cpp/rulebased/def/si.h"
-#include "ash/services/ime/public/cpp/rulebased/def/ta_inscript.h"
-#include "ash/services/ime/public/cpp/rulebased/def/ta_itrans.h"
-#include "ash/services/ime/public/cpp/rulebased/def/ta_phone.h"
-#include "ash/services/ime/public/cpp/rulebased/def/ta_tamil99.h"
-#include "ash/services/ime/public/cpp/rulebased/def/ta_typewriter.h"
-#include "ash/services/ime/public/cpp/rulebased/def/te_phone.h"
-#include "ash/services/ime/public/cpp/rulebased/def/th.h"
-#include "ash/services/ime/public/cpp/rulebased/def/th_pattajoti.h"
-#include "ash/services/ime/public/cpp/rulebased/def/th_tis.h"
-#include "ash/services/ime/public/cpp/rulebased/def/us.h"
-#include "ash/services/ime/public/cpp/rulebased/def/vi_tcvn.h"
-#include "ash/services/ime/public/cpp/rulebased/def/vi_telex.h"
-#include "ash/services/ime/public/cpp/rulebased/def/vi_viqr.h"
-#include "ash/services/ime/public/cpp/rulebased/def/vi_vni.h"
-#include "ash/services/ime/public/mojom/input_method.mojom-shared.h"
 #include "base/containers/contains.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ar.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/bn_phone.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ckb_ar.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ckb_en.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/deva_phone.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ethi.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/fa.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/gu_phone.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/hi_inscript.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/km.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/kn_phone.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/lo.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ml_phone.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/my.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/my_myansan.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ne_inscript.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ne_phone.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ru_phone_aatseel.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ru_phone_yazhert.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/si.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ta_inscript.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ta_itrans.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ta_phone.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ta_tamil99.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/ta_typewriter.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/te_phone.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/th.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/th_pattajoti.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/th_tis.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/us.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/vi_tcvn.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/vi_telex.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/vi_viqr.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/def/vi_vni.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method.mojom-shared.h"
 #include "third_party/re2/src/re2/re2.h"
 
 namespace ash {
diff --git a/ash/services/ime/public/cpp/rulebased/rules_data.h b/chromeos/ash/services/ime/public/cpp/rulebased/rules_data.h
similarity index 91%
rename from ash/services/ime/public/cpp/rulebased/rules_data.h
rename to chromeos/ash/services/ime/public/cpp/rulebased/rules_data.h
index 4f6a43a4..5a8e14db 100644
--- a/ash/services/ime/public/cpp/rulebased/rules_data.h
+++ b/chromeos/ash/services/ime/public/cpp/rulebased/rules_data.h
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_RULES_DATA_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_RULES_DATA_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_RULES_DATA_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_RULES_DATA_H_
 
 #include <map>
 #include <memory>
 #include <string>
 #include <utility>
 
-#include "ash/services/ime/public/mojom/input_method.mojom-shared.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method.mojom-shared.h"
 
 namespace re2 {
 class RE2;
@@ -93,4 +93,4 @@
 }  // namespace ime
 }  // namespace ash
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_RULES_DATA_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_RULEBASED_RULES_DATA_H_
diff --git a/ash/services/ime/public/cpp/rulebased/test_data/arabic b/chromeos/ash/services/ime/public/cpp/rulebased/test_data/arabic
similarity index 100%
rename from ash/services/ime/public/cpp/rulebased/test_data/arabic
rename to chromeos/ash/services/ime/public/cpp/rulebased/test_data/arabic
diff --git a/ash/services/ime/public/cpp/rulebased/test_data/deva_phone b/chromeos/ash/services/ime/public/cpp/rulebased/test_data/deva_phone
similarity index 100%
rename from ash/services/ime/public/cpp/rulebased/test_data/deva_phone
rename to chromeos/ash/services/ime/public/cpp/rulebased/test_data/deva_phone
diff --git a/ash/services/ime/public/cpp/rulebased/test_data/deva_phone_backspace b/chromeos/ash/services/ime/public/cpp/rulebased/test_data/deva_phone_backspace
similarity index 100%
rename from ash/services/ime/public/cpp/rulebased/test_data/deva_phone_backspace
rename to chromeos/ash/services/ime/public/cpp/rulebased/test_data/deva_phone_backspace
diff --git a/ash/services/ime/public/cpp/rulebased/test_data/deva_phone_enter b/chromeos/ash/services/ime/public/cpp/rulebased/test_data/deva_phone_enter
similarity index 100%
rename from ash/services/ime/public/cpp/rulebased/test_data/deva_phone_enter
rename to chromeos/ash/services/ime/public/cpp/rulebased/test_data/deva_phone_enter
diff --git a/ash/services/ime/public/cpp/rulebased/test_data/deva_phone_transforms b/chromeos/ash/services/ime/public/cpp/rulebased/test_data/deva_phone_transforms
similarity index 100%
rename from ash/services/ime/public/cpp/rulebased/test_data/deva_phone_transforms
rename to chromeos/ash/services/ime/public/cpp/rulebased/test_data/deva_phone_transforms
diff --git a/ash/services/ime/public/cpp/rulebased/test_data/persian b/chromeos/ash/services/ime/public/cpp/rulebased/test_data/persian
similarity index 100%
rename from ash/services/ime/public/cpp/rulebased/test_data/persian
rename to chromeos/ash/services/ime/public/cpp/rulebased/test_data/persian
diff --git a/ash/services/ime/public/cpp/rulebased/test_data/thai b/chromeos/ash/services/ime/public/cpp/rulebased/test_data/thai
similarity index 100%
rename from ash/services/ime/public/cpp/rulebased/test_data/thai
rename to chromeos/ash/services/ime/public/cpp/rulebased/test_data/thai
diff --git a/ash/services/ime/public/cpp/rulebased/test_data/thai_pattajoti b/chromeos/ash/services/ime/public/cpp/rulebased/test_data/thai_pattajoti
similarity index 100%
rename from ash/services/ime/public/cpp/rulebased/test_data/thai_pattajoti
rename to chromeos/ash/services/ime/public/cpp/rulebased/test_data/thai_pattajoti
diff --git a/ash/services/ime/public/cpp/rulebased/test_data/thai_tis b/chromeos/ash/services/ime/public/cpp/rulebased/test_data/thai_tis
similarity index 100%
rename from ash/services/ime/public/cpp/rulebased/test_data/thai_tis
rename to chromeos/ash/services/ime/public/cpp/rulebased/test_data/thai_tis
diff --git a/ash/services/ime/public/cpp/shared_lib/BUILD.gn b/chromeos/ash/services/ime/public/cpp/shared_lib/BUILD.gn
similarity index 100%
rename from ash/services/ime/public/cpp/shared_lib/BUILD.gn
rename to chromeos/ash/services/ime/public/cpp/shared_lib/BUILD.gn
diff --git a/ash/services/ime/public/cpp/shared_lib/interfaces.h b/chromeos/ash/services/ime/public/cpp/shared_lib/interfaces.h
similarity index 98%
rename from ash/services/ime/public/cpp/shared_lib/interfaces.h
rename to chromeos/ash/services/ime/public/cpp/shared_lib/interfaces.h
index ba1b41c8..9a205ff4 100644
--- a/ash/services/ime/public/cpp/shared_lib/interfaces.h
+++ b/chromeos/ash/services/ime/public/cpp/shared_lib/interfaces.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 ASH_SERVICES_IME_PUBLIC_CPP_SHARED_LIB_INTERFACES_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_SHARED_LIB_INTERFACES_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_SHARED_LIB_INTERFACES_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_SHARED_LIB_INTERFACES_H_
 
 #include <stddef.h>
 #include <stdint.h>
@@ -284,4 +284,4 @@
 
 }  // extern "C"
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_SHARED_LIB_INTERFACES_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_SHARED_LIB_INTERFACES_H_
diff --git a/ash/services/ime/public/cpp/suggestions.h b/chromeos/ash/services/ime/public/cpp/suggestions.h
similarity index 84%
rename from ash/services/ime/public/cpp/suggestions.h
rename to chromeos/ash/services/ime/public/cpp/suggestions.h
index 777250c..8faef993 100644
--- a/ash/services/ime/public/cpp/suggestions.h
+++ b/chromeos/ash/services/ime/public/cpp/suggestions.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 ASH_SERVICES_IME_PUBLIC_CPP_SUGGESTIONS_H_
-#define ASH_SERVICES_IME_PUBLIC_CPP_SUGGESTIONS_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_SUGGESTIONS_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_SUGGESTIONS_H_
 
 #include <string>
 
@@ -48,4 +48,4 @@
 }  // namespace ime
 }  // namespace ash
 
-#endif  // ASH_SERVICES_IME_PUBLIC_CPP_SUGGESTIONS_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_CPP_SUGGESTIONS_H_
diff --git a/ash/services/ime/public/mojom/BUILD.gn b/chromeos/ash/services/ime/public/mojom/BUILD.gn
similarity index 95%
rename from ash/services/ime/public/mojom/BUILD.gn
rename to chromeos/ash/services/ime/public/mojom/BUILD.gn
index 1bb799a..f7a9ea1 100644
--- a/ash/services/ime/public/mojom/BUILD.gn
+++ b/chromeos/ash/services/ime/public/mojom/BUILD.gn
@@ -50,7 +50,7 @@
       traits_headers = [ "mojom_traits.h" ]
       traits_sources = [ "mojom_traits.cc" ]
       traits_public_deps = [
-        "//ash/services/ime/public/cpp:structs",
+        "//chromeos/ash/services/ime/public/cpp:structs",
         "//ui/gfx/range",
       ]
     },
diff --git a/ash/services/ime/public/mojom/OWNERS b/chromeos/ash/services/ime/public/mojom/OWNERS
similarity index 100%
rename from ash/services/ime/public/mojom/OWNERS
rename to chromeos/ash/services/ime/public/mojom/OWNERS
diff --git a/ash/services/ime/public/mojom/connection_factory.mojom b/chromeos/ash/services/ime/public/mojom/connection_factory.mojom
similarity index 85%
rename from ash/services/ime/public/mojom/connection_factory.mojom
rename to chromeos/ash/services/ime/public/mojom/connection_factory.mojom
index c8379dc8..9e251fd 100644
--- a/ash/services/ime/public/mojom/connection_factory.mojom
+++ b/chromeos/ash/services/ime/public/mojom/connection_factory.mojom
@@ -10,8 +10,8 @@
 
 module ash.ime.mojom;
 
-import "ash/services/ime/public/mojom/input_method.mojom";
-import "ash/services/ime/public/mojom/input_method_host.mojom";
+import "chromeos/ash/services/ime/public/mojom/input_method.mojom";
+import "chromeos/ash/services/ime/public/mojom/input_method_host.mojom";
 
 // Responsible for instantiating the connection between the shared library
 // and Chromium over an associated Mojo pipe.
diff --git a/ash/services/ime/public/mojom/ime_service.mojom b/chromeos/ash/services/ime/public/mojom/ime_service.mojom
similarity index 94%
rename from ash/services/ime/public/mojom/ime_service.mojom
rename to chromeos/ash/services/ime/public/mojom/ime_service.mojom
index fee660f..dd73add 100644
--- a/ash/services/ime/public/mojom/ime_service.mojom
+++ b/chromeos/ash/services/ime/public/mojom/ime_service.mojom
@@ -4,10 +4,10 @@
 
 module ash.ime.mojom;
 
-import "ash/services/ime/public/mojom/connection_factory.mojom";
-import "ash/services/ime/public/mojom/input_engine.mojom";
-import "ash/services/ime/public/mojom/input_method.mojom";
-import "ash/services/ime/public/mojom/input_method_host.mojom";
+import "chromeos/ash/services/ime/public/mojom/connection_factory.mojom";
+import "chromeos/ash/services/ime/public/mojom/input_engine.mojom";
+import "chromeos/ash/services/ime/public/mojom/input_method.mojom";
+import "chromeos/ash/services/ime/public/mojom/input_method_host.mojom";
 import "mojo/public/mojom/base/file_path.mojom";
 import "url/mojom/url.mojom";
 import "sandbox/policy/mojom/sandbox.mojom";
diff --git a/ash/services/ime/public/mojom/input_engine.mojom b/chromeos/ash/services/ime/public/mojom/input_engine.mojom
similarity index 91%
rename from ash/services/ime/public/mojom/input_engine.mojom
rename to chromeos/ash/services/ime/public/mojom/input_engine.mojom
index 83e48e9..5be2d14 100644
--- a/ash/services/ime/public/mojom/input_engine.mojom
+++ b/chromeos/ash/services/ime/public/mojom/input_engine.mojom
@@ -14,7 +14,8 @@
 // Note that only closed source proto messages are allowed to be sent via
 // the ProcessMessage() method. All other proto messages must be mirrored with
 // a respective mojom method here in this interface for security (see
-// ash/services/ime/decoder/system_engine.cc for an example of mirroring).
+// chromeos/ash/services/ime/decoder/system_engine.cc for an example of
+// mirroring).
 interface InputChannel {
   // Returns a serialized protobuf result after processing a serialized
   // protobuf message.
diff --git a/ash/services/ime/public/mojom/input_method.mojom b/chromeos/ash/services/ime/public/mojom/input_method.mojom
similarity index 100%
rename from ash/services/ime/public/mojom/input_method.mojom
rename to chromeos/ash/services/ime/public/mojom/input_method.mojom
diff --git a/ash/services/ime/public/mojom/input_method_host.mojom b/chromeos/ash/services/ime/public/mojom/input_method_host.mojom
similarity index 97%
rename from ash/services/ime/public/mojom/input_method_host.mojom
rename to chromeos/ash/services/ime/public/mojom/input_method_host.mojom
index 23ae235..bbc3c34 100644
--- a/ash/services/ime/public/mojom/input_method_host.mojom
+++ b/chromeos/ash/services/ime/public/mojom/input_method_host.mojom
@@ -6,11 +6,11 @@
 // the Chromium repo. This file should be updated first, before syncing in the
 // other repos.
 
-// Next MinVersion: 8
+// Next MinVersion: 9
 
 module ash.ime.mojom;
 
-import "ash/services/ime/public/mojom/input_method.mojom";
+import "chromeos/ash/services/ime/public/mojom/input_method.mojom";
 import "mojo/public/mojom/base/string16.mojom";
 
 // Do not modify this enum. If new values are needed, deprecate the entire enum.
@@ -238,7 +238,7 @@
 // Provides a way for the InputMethod, which lives in a Chrome utility process,
 // to communicate back to the browser process.
 //
-// Next ordinal: 14
+// Next ordinal: 15
 [Stable]
 interface InputMethodHost {
   // ========================================================
@@ -352,4 +352,8 @@
   // - The layout setting is recorded in UMA as
   //   InputMethod.PhysicalKeyboard.Korean.Layout.
   [MinVersion=3] ReportKoreanSettings@11(KoreanSettings settings);
+
+  // Reports an opportunity identified in the current text to show a predictive
+  // text suggestions.
+  [MinVersion=8] ReportSuggestionOpportunity@14(SuggestionMode mode);
 };
diff --git a/ash/services/ime/public/mojom/mojom_traits.cc b/chromeos/ash/services/ime/public/mojom/mojom_traits.cc
similarity index 95%
rename from ash/services/ime/public/mojom/mojom_traits.cc
rename to chromeos/ash/services/ime/public/mojom/mojom_traits.cc
index 707e3992..4fa9e98f 100644
--- a/ash/services/ime/public/mojom/mojom_traits.cc
+++ b/chromeos/ash/services/ime/public/mojom/mojom_traits.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 "ash/services/ime/public/mojom/mojom_traits.h"
+#include "chromeos/ash/services/ime/public/mojom/mojom_traits.h"
 
-#include "ash/services/ime/public/mojom/input_method_host.mojom-shared.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method_host.mojom-shared.h"
 
 namespace mojo {
 namespace {
diff --git a/ash/services/ime/public/mojom/mojom_traits.h b/chromeos/ash/services/ime/public/mojom/mojom_traits.h
similarity index 89%
rename from ash/services/ime/public/mojom/mojom_traits.h
rename to chromeos/ash/services/ime/public/mojom/mojom_traits.h
index 63657d4..cd65692 100644
--- a/ash/services/ime/public/mojom/mojom_traits.h
+++ b/chromeos/ash/services/ime/public/mojom/mojom_traits.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 ASH_SERVICES_IME_PUBLIC_MOJOM_MOJOM_TRAITS_H_
-#define ASH_SERVICES_IME_PUBLIC_MOJOM_MOJOM_TRAITS_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_PUBLIC_MOJOM_MOJOM_TRAITS_H_
+#define CHROMEOS_ASH_SERVICES_IME_PUBLIC_MOJOM_MOJOM_TRAITS_H_
 
-#include "ash/services/ime/public/cpp/suggestions.h"
-#include "ash/services/ime/public/mojom/input_method_host.mojom-shared.h"
+#include "chromeos/ash/services/ime/public/cpp/suggestions.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method_host.mojom-shared.h"
 #include "mojo/public/cpp/bindings/enum_traits.h"
 #include "mojo/public/cpp/bindings/struct_traits.h"
 #include "ui/gfx/range/range.h"
@@ -88,4 +88,4 @@
 
 }  // namespace mojo
 
-#endif  // ASH_SERVICES_IME_PUBLIC_MOJOM_MOJOM_TRAITS_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_PUBLIC_MOJOM_MOJOM_TRAITS_H_
diff --git a/ash/services/ime/rule_based_engine.cc b/chromeos/ash/services/ime/rule_based_engine.cc
similarity index 98%
rename from ash/services/ime/rule_based_engine.cc
rename to chromeos/ash/services/ime/rule_based_engine.cc
index dc8f994..5f08a46 100644
--- a/ash/services/ime/rule_based_engine.cc
+++ b/chromeos/ash/services/ime/rule_based_engine.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 "ash/services/ime/rule_based_engine.h"
+#include "chromeos/ash/services/ime/rule_based_engine.h"
 
 #include "base/i18n/icu_string_conversions.h"
 #include "base/notreached.h"
diff --git a/ash/services/ime/rule_based_engine.h b/chromeos/ash/services/ime/rule_based_engine.h
similarity index 86%
rename from ash/services/ime/rule_based_engine.h
rename to chromeos/ash/services/ime/rule_based_engine.h
index 7464147..c8dc278 100644
--- a/ash/services/ime/rule_based_engine.h
+++ b/chromeos/ash/services/ime/rule_based_engine.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 ASH_SERVICES_IME_RULE_BASED_ENGINE_H_
-#define ASH_SERVICES_IME_RULE_BASED_ENGINE_H_
+#ifndef CHROMEOS_ASH_SERVICES_IME_RULE_BASED_ENGINE_H_
+#define CHROMEOS_ASH_SERVICES_IME_RULE_BASED_ENGINE_H_
 
-#include "ash/services/ime/public/cpp/rulebased/engine.h"
-#include "ash/services/ime/public/cpp/suggestions.h"
-#include "ash/services/ime/public/mojom/input_method.mojom.h"
-#include "ash/services/ime/public/mojom/input_method_host.mojom.h"
+#include "chromeos/ash/services/ime/public/cpp/rulebased/engine.h"
+#include "chromeos/ash/services/ime/public/cpp/suggestions.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method.mojom.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method_host.mojom.h"
 #include "mojo/public/cpp/bindings/associated_receiver.h"
 #include "mojo/public/cpp/bindings/associated_remote.h"
 #include "mojo/public/cpp/bindings/pending_associated_receiver.h"
@@ -74,4 +74,4 @@
 }  // namespace ime
 }  // namespace ash
 
-#endif  // ASH_SERVICES_IME_RULE_BASED_ENGINE_H_
+#endif  // CHROMEOS_ASH_SERVICES_IME_RULE_BASED_ENGINE_H_
diff --git a/chromeos/profiles/arm.afdo.newest.txt b/chromeos/profiles/arm.afdo.newest.txt
index 1794cb26..e000e4e3 100644
--- a/chromeos/profiles/arm.afdo.newest.txt
+++ b/chromeos/profiles/arm.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-arm-none-108-5323.0-1664790676-benchmark-108.0.5344.0-r1-redacted.afdo.xz
+chromeos-chrome-arm-none-108-5335.0-1665395930-benchmark-108.0.5355.0-r2-redacted.afdo.xz
diff --git a/chromeos/services/network_config/public/cpp/cros_network_config_observer.h b/chromeos/services/network_config/public/cpp/cros_network_config_observer.h
index 9252f86..85887729 100644
--- a/chromeos/services/network_config/public/cpp/cros_network_config_observer.h
+++ b/chromeos/services/network_config/public/cpp/cros_network_config_observer.h
@@ -27,4 +27,9 @@
 
 }  // namespace chromeos::network_config
 
+// TODO(https://crbug.com/1164001): remove when it moved to ash.
+namespace ash::network_config {
+using ::chromeos::network_config::CrosNetworkConfigObserver;
+}
+
 #endif  // CHROMEOS_SERVICES_NETWORK_CONFIG_PUBLIC_CPP_CROS_NETWORK_CONFIG_OBSERVER_H_
diff --git a/components/autofill_assistant/browser/js_flow_executor_impl.cc b/components/autofill_assistant/browser/js_flow_executor_impl.cc
index 74e8cb2..5b69b20 100644
--- a/components/autofill_assistant/browser/js_flow_executor_impl.cc
+++ b/components/autofill_assistant/browser/js_flow_executor_impl.cc
@@ -370,7 +370,7 @@
     std::unique_ptr<runtime::EvaluateResult> result) {
   const JsLineOffsets js_line_offsets = {
       {js_flow_util::GetDevtoolsSourceUrl(UnexpectedErrorInfoProto::JS_FLOW),
-       {kJsLineOffset, kJsLineOffset + CountLines(*js_flow_)}}};
+       {.begin = kJsLineOffset, .end = kJsLineOffset + CountLines(*js_flow_)}}};
   // Check and extract the return value. In case of exceptions, the sanitized
   // stack trace will be part of the returned ClientStatus. Only primitive
   // values are allowed (see js_flow_util::ExtractFlowReturnValue for details).
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto
index 23fe10c0..ca714516 100644
--- a/components/autofill_assistant/browser/service.proto
+++ b/components/autofill_assistant/browser/service.proto
@@ -1624,6 +1624,8 @@
     optional SelectorProto.SemanticFilter semantic_filter = 4;
     // The element's backend node id.
     optional int32 backend_node_id = 3;
+    // Whether this element was found using a feature override.
+    optional bool used_override = 5;
 
     reserved 1, 2;
   }
diff --git a/components/autofill_assistant/browser/web/element_finder.cc b/components/autofill_assistant/browser/web/element_finder.cc
index a5e7ca8..6c59879b2 100644
--- a/components/autofill_assistant/browser/web/element_finder.cc
+++ b/components/autofill_assistant/browser/web/element_finder.cc
@@ -123,7 +123,7 @@
 
   if (selector_.proto.filters_size() > 1) {
     // The semantic filter was only the root, there are more filters to run.
-    // Log and retain teh current result and start a CSS lookup from here.
+    // Log and retain the current result and start a CSS lookup from here.
     UpdateLogInfo(status);
     current_result_ = std::move(result);
 
diff --git a/components/autofill_assistant/browser/web/semantic_element_finder.cc b/components/autofill_assistant/browser/web/semantic_element_finder.cc
index 726b5b55..546d41a 100644
--- a/components/autofill_assistant/browser/web/semantic_element_finder.cc
+++ b/components/autofill_assistant/browser/web/semantic_element_finder.cc
@@ -21,6 +21,7 @@
 #include "content/public/browser/global_routing_id.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents.h"
+#include "element.h"
 
 namespace autofill_assistant {
 
@@ -74,7 +75,7 @@
   SendResult(status, ElementFinderResult::EmptyResult());
 }
 
-void SemanticElementFinder::ResultFound(const GlobalBackendNodeId& node_id,
+void SemanticElementFinder::ResultFound(const SemanticNodeResult& node,
                                         const std::string& object_id,
                                         const std::string& devtools_frame_id) {
   if (!callback_) {
@@ -82,10 +83,10 @@
   }
 
   ElementFinderResult result;
-  result.SetRenderFrameHostGlobalId(node_id.host_id());
+  result.SetRenderFrameHostGlobalId(node.id.host_id());
   result.SetObjectId(object_id);
   result.SetNodeFrameId(devtools_frame_id);
-  result.SetBackendNodeId(node_id.backend_node_id());
+  result.SetBackendNodeId(node.id.backend_node_id());
 
   SendResult(OkClientStatus(), result);
 }
@@ -120,13 +121,15 @@
     auto* predicted_element =
         info.mutable_semantic_inference_result()->add_predicted_elements();
     predicted_element->set_backend_node_id(
-        semantic_node_result.backend_node_id());
+        semantic_node_result.id.backend_node_id());
     *predicted_element->mutable_semantic_filter() = filter_;
     // TODO(b/217160707): For the ignore_objective case this is not correct
     // and the inferred objective should be returned from the Agent and used
     // here.
+    if (semantic_node_result.used_override) {
+      predicted_element->set_used_override(semantic_node_result.used_override);
+    }
   }
-
   return info;
 }
 
@@ -156,7 +159,6 @@
 }
 
 void SemanticElementFinder::OnTimeout() {
-  VLOG(1) << "AnnotateDomModel timeout.";
   Finalize();
 }
 
@@ -194,20 +196,22 @@
 
   node_data_frame_status_.emplace_back(status);
 
-  std::vector<GlobalBackendNodeId> node_ids;
+  std::vector<SemanticNodeResult> results;
   for (const auto& node : node_data) {
-    node_ids.emplace_back(GlobalBackendNodeId(host_id, node.backend_node_id));
+    SemanticNodeResult node_result;
+    node_result.id = GlobalBackendNodeId(host_id, node.backend_node_id);
+    node_result.used_override = node.used_override;
+    results.emplace_back(node_result);
   }
-
-  received_results_.emplace(host_id, std::move(node_ids));
+  received_results_.emplace(host_id, std::move(results));
 
   MarkRenderFrameProcessed(host_id);
 }
 
 void SemanticElementFinder::OnRunAnnotateDomModel() {
-  for (const auto& [backend_id, node_ids] : received_results_) {
-    semantic_node_results_.insert(semantic_node_results_.end(),
-                                  node_ids.begin(), node_ids.end());
+  for (const auto& [backend_id, results] : received_results_) {
+    semantic_node_results_.insert(semantic_node_results_.end(), results.begin(),
+                                  results.end());
   }
 
   // For now we only support finding a single element.
@@ -238,7 +242,7 @@
   // not have a session id in our |DevtoolsClient|).
   std::string devtools_frame_id;
   auto* frame =
-      content::RenderFrameHost::FromID(semantic_node_result.host_id());
+      content::RenderFrameHost::FromID(semantic_node_result.id.host_id());
   if (frame != nullptr && frame->IsRenderFrameLive() &&
       web_contents_->GetPrimaryMainFrame()->GetProcess() !=
           frame->GetProcess()) {
@@ -249,7 +253,7 @@
 
   devtools_client_->GetDOM()->ResolveNode(
       dom::ResolveNodeParams::Builder()
-          .SetBackendNodeId(semantic_node_result.backend_node_id())
+          .SetBackendNodeId(semantic_node_result.id.backend_node_id())
           .Build(),
       devtools_frame_id,
       base::BindOnce(&SemanticElementFinder::OnResolveNodeForAnnotateDom,
@@ -258,7 +262,7 @@
 }
 
 void SemanticElementFinder::OnResolveNodeForAnnotateDom(
-    const GlobalBackendNodeId& node,
+    const SemanticNodeResult& node,
     const std::string& devtools_frame_id,
     const DevtoolsClient::ReplyStatus& reply_status,
     std::unique_ptr<dom::ResolveNodeResult> result) {
diff --git a/components/autofill_assistant/browser/web/semantic_element_finder.h b/components/autofill_assistant/browser/web/semantic_element_finder.h
index d558be94..a54d68d9 100644
--- a/components/autofill_assistant/browser/web/semantic_element_finder.h
+++ b/components/autofill_assistant/browser/web/semantic_element_finder.h
@@ -36,6 +36,11 @@
 class SemanticElementFinder : public BaseElementFinder,
                               public content::WebContentsObserver {
  public:
+  struct SemanticNodeResult {
+    GlobalBackendNodeId id = GlobalBackendNodeId(nullptr, -1);
+    bool used_override = false;
+  };
+
   SemanticElementFinder(content::WebContents* web_contents,
                         DevtoolsClient* devtools_client,
                         AnnotateDomModelService* annotate_dom_model_service,
@@ -59,7 +64,7 @@
 
   // Builds a result from the provided information and returns it with an
   // ok status.
-  void ResultFound(const GlobalBackendNodeId& node_id,
+  void ResultFound(const SemanticNodeResult& node_id,
                    const std::string& object_id,
                    const std::string& devtools_frame_id);
 
@@ -84,7 +89,7 @@
   void OnRunAnnotateDomModel();
 
   void OnResolveNodeForAnnotateDom(
-      const GlobalBackendNodeId& node,
+      const SemanticNodeResult& node,
       const std::string& devtools_frame_id,
       const DevtoolsClient::ReplyStatus& reply_status,
       std::unique_ptr<dom::ResolveNodeResult> result);
@@ -111,11 +116,11 @@
 
   // Elements gathered through all frames. Unused if the |selector_| does not
   // contain |SemanticInformation|.
-  std::vector<GlobalBackendNodeId> semantic_node_results_;
+  std::vector<SemanticNodeResult> semantic_node_results_;
   std::vector<mojom::NodeDataStatus> node_data_frame_status_;
 
   std::set<content::GlobalRenderFrameHostId> expected_frame_ids_;
-  std::map<content::GlobalRenderFrameHostId, std::vector<GlobalBackendNodeId>>
+  std::map<content::GlobalRenderFrameHostId, std::vector<SemanticNodeResult>>
       received_results_;
 
   std::unique_ptr<base::OneShotTimer> timer_ = nullptr;
diff --git a/components/autofill_assistant/browser/web/semantic_element_finder_browsertest.cc b/components/autofill_assistant/browser/web/semantic_element_finder_browsertest.cc
index bbacd796..18937ea1 100644
--- a/components/autofill_assistant/browser/web/semantic_element_finder_browsertest.cc
+++ b/components/autofill_assistant/browser/web/semantic_element_finder_browsertest.cc
@@ -328,6 +328,15 @@
   ClientStatus status = RunWaitForDom(action_proto, /* use_observers= */ false,
                                       run_expectations.Get());
   EXPECT_EQ(status.proto_status(), ACTION_APPLIED);
+
+  ASSERT_EQ(log_info_.element_finder_info().size(), 1);
+  const auto& result =
+      log_info_.element_finder_info(0).semantic_inference_result();
+  ASSERT_EQ(1, result.predicted_elements().size());
+  EXPECT_EQ(backend_node_id, result.predicted_elements(0).backend_node_id());
+  EXPECT_THAT(1, result.predicted_elements(0).semantic_filter().role());
+  EXPECT_THAT(2, result.predicted_elements(0).semantic_filter().objective());
+  EXPECT_FALSE(result.predicted_elements(0).used_override());
 }
 
 IN_PROC_BROWSER_TEST_F(SemanticElementFinderBrowserTest,
@@ -816,4 +825,56 @@
   EXPECT_EQ(option_status.proto_status(), TIMED_OUT);
 }
 
+#if BUILDFLAG(IS_ANDROID)
+IN_PROC_BROWSER_TEST_F(SemanticElementFinderBrowserTest,
+                       WaitForDomForSemanticElementWithOverride) {
+  // This element is unique.
+  SelectorProto baseline_selector = ToSelectorProto("#select");
+
+  ClientStatus element_status;
+  int backend_node_id =
+      GetBackendNodeId(Selector(baseline_selector), &element_status);
+  EXPECT_TRUE(element_status.ok());
+
+  NodeData node_data;
+  node_data.backend_node_id = backend_node_id;
+  node_data.used_override = true;
+  EXPECT_CALL(autofill_assistant_agent_,
+              GetSemanticNodes(1, 2, false, base::Milliseconds(5000), _))
+      .WillOnce(RunOnceCallback<4>(mojom::NodeDataStatus::kSuccess,
+                                   std::vector<NodeData>{node_data}))
+      // Capture any other frames.
+      .WillRepeatedly(RunOnceCallback<4>(
+          mojom::NodeDataStatus::kUnexpectedError, std::vector<NodeData>()));
+
+  ActionProto action_proto;
+  auto* wait_for_dom = action_proto.mutable_wait_for_dom();
+  auto* condition = wait_for_dom->mutable_wait_condition();
+  condition->mutable_client_id()->set_identifier("e");
+  condition->set_require_unique_element(true);
+  auto* semantic_filter =
+      condition->mutable_match()->add_filters()->mutable_semantic();
+  semantic_filter->set_role(1);
+  semantic_filter->set_objective(2);
+
+  base::MockCallback<base::OnceCallback<void(ScriptExecutor*)>>
+      run_expectations;
+  EXPECT_CALL(run_expectations, Run(_))
+      .WillOnce([](ScriptExecutor* script_executor) {
+        EXPECT_TRUE(script_executor->GetElementStore()->HasElement("e"));
+      });
+  ClientStatus status = RunWaitForDom(action_proto, /* use_observers= */ false,
+                                      run_expectations.Get());
+  EXPECT_EQ(status.proto_status(), ACTION_APPLIED);
+  ASSERT_EQ(log_info_.element_finder_info().size(), 1);
+  const auto& result =
+      log_info_.element_finder_info(0).semantic_inference_result();
+  ASSERT_EQ(1, result.predicted_elements().size());
+  EXPECT_EQ(backend_node_id, result.predicted_elements(0).backend_node_id());
+  EXPECT_THAT(1, result.predicted_elements(0).semantic_filter().role());
+  EXPECT_THAT(2, result.predicted_elements(0).semantic_filter().objective());
+  EXPECT_TRUE(result.predicted_elements(0).used_override());
+}
+#endif
+
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/web/web_controller_util.cc b/components/autofill_assistant/browser/web/web_controller_util.cc
index 6426320..83934908 100644
--- a/components/autofill_assistant/browser/web/web_controller_util.cc
+++ b/components/autofill_assistant/browser/web/web_controller_util.cc
@@ -25,14 +25,17 @@
                         UnexpectedErrorInfoProto* info) {
   int line_number = s.GetLineNumber();
   if (js_line_offsets.contains(devtools_source_url)) {
-    const auto [begin, end] = js_line_offsets.at(devtools_source_url);
+    const JsLineOffsetRange& js_line_offset_range =
+        js_line_offsets.at(devtools_source_url);
 
     // If the line number is outside of the lines for which we want to generate
     // a stack entry we return.
-    if (line_number < begin || line_number > end) {
+    if (line_number < js_line_offset_range.begin ||
+        line_number > js_line_offset_range.end) {
       return;
     }
-    line_number -= begin;
+    // Set the line number relative to the offset range.
+    line_number -= js_line_offset_range.begin;
   }
 
   info->add_js_exception_locations(
diff --git a/components/autofill_assistant/browser/web/web_controller_util.h b/components/autofill_assistant/browser/web/web_controller_util.h
index 080890e..e703c79 100644
--- a/components/autofill_assistant/browser/web/web_controller_util.h
+++ b/components/autofill_assistant/browser/web/web_controller_util.h
@@ -32,11 +32,16 @@
     const std::string& file,
     int line);
 
-// Map from devtools source url to js line offset pair. The js line offset pair
-// consists of the begin and end. The begin/end is the first/last line for which
-// we want to generate a stack entry. See js_flow_util for details on devtools
-// source urls.
-using JsLineOffsets = base::flat_map<std::string, std::pair<int, int>>;
+// Wrapper for the js line offset range. The begin/end of the range represents
+// the first/last line for which we want to generate a stack entry.
+struct JsLineOffsetRange {
+  int begin;
+  int end;
+};
+
+// Map from devtools source url to js line offset range.
+// See js_flow_util for details on devtools source urls.
+using JsLineOffsets = base::flat_map<std::string, JsLineOffsetRange>;
 
 // Builds a ClientStatus appropriate for a JavaScript error.
 ClientStatus JavaScriptErrorStatus(
@@ -68,7 +73,7 @@
   return OkClientStatus();
 }
 
-// Fills a ClientStatus with appropriate details from the
+// Fills a ClientStatus with appropriate details from the failed web action
 void FillWebControllerErrorInfo(
     WebControllerErrorInfoProto::WebAction failed_web_action,
     ClientStatus* status);
diff --git a/components/autofill_assistant/content/browser/content_autofill_assistant_driver.cc b/components/autofill_assistant/content/browser/content_autofill_assistant_driver.cc
index 2aaf5a6..1ecfb916 100644
--- a/components/autofill_assistant/content/browser/content_autofill_assistant_driver.cc
+++ b/components/autofill_assistant/content/browser/content_autofill_assistant_driver.cc
@@ -7,7 +7,6 @@
 #include "base/files/file.h"
 #include "base/guid.h"
 #include "base/location.h"
-#include "base/logging.h"
 #include "components/autofill_assistant/content/common/proto/semantic_feature_overrides.pb.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
@@ -35,7 +34,6 @@
         pending_receiver,
     content::RenderFrameHost* render_frame_host) {
   DCHECK(render_frame_host);
-
   auto* driver = ContentAutofillAssistantDriver::GetOrCreateForCurrentDocument(
       render_frame_host);
   if (driver) {
@@ -78,7 +76,6 @@
     base::TimeDelta timeout,
     GetAnnotateDomModelCallback callback) {
   if (!annotate_dom_model_service_) {
-    LOG(ERROR) << "No model service";
     std::move(callback).Run(mojom::ModelStatus::kUnexpectedError, base::File(),
                             /*overrides_policy=*/"");
     return;
@@ -131,7 +128,6 @@
   if (it == pending_calls_.end()) {
     return;
   }
-
   DCHECK(it->second->callback_);
   std::move(it->second->callback_)
       .Run(model_status, std::move(model_file), GetOverridesPolicy());
@@ -140,12 +136,13 @@
 
 void ContentAutofillAssistantDriver::SetAnnotateDomModelService(
     AnnotateDomModelService* annotate_dom_model_service) {
-  DCHECK(annotate_dom_model_service);
   annotate_dom_model_service_ = annotate_dom_model_service;
 }
 
 std::string ContentAutofillAssistantDriver::GetOverridesPolicy() const {
-  DCHECK(annotate_dom_model_service_);
+  if (!annotate_dom_model_service_) {
+    return "";
+  }
   return annotate_dom_model_service_->GetOverridesPolicy();
 }
 
diff --git a/components/autofill_assistant/content/renderer/BUILD.gn b/components/autofill_assistant/content/renderer/BUILD.gn
index 81035a9c..a5fa3cd 100644
--- a/components/autofill_assistant/content/renderer/BUILD.gn
+++ b/components/autofill_assistant/content/renderer/BUILD.gn
@@ -13,8 +13,7 @@
   sources = [
     "autofill_assistant_agent.cc",
     "autofill_assistant_agent.h",
-    "autofill_assistant_agent_debug_utils.cc",
-    "autofill_assistant_agent_debug_utils.h",
+    "autofill_assistant_model_executor_result.h",
   ]
 
   deps = [
@@ -34,6 +33,8 @@
 
   if (build_with_tflite_lib) {
     sources += [
+      "autofill_assistant_agent_debug_utils.cc",
+      "autofill_assistant_agent_debug_utils.h",
       "autofill_assistant_model_executor.cc",
       "autofill_assistant_model_executor.h",
     ]
diff --git a/components/autofill_assistant/content/renderer/autofill_assistant_agent.cc b/components/autofill_assistant/content/renderer/autofill_assistant_agent.cc
index 7d0d7590..67ef6cd8a 100644
--- a/components/autofill_assistant/content/renderer/autofill_assistant_agent.cc
+++ b/components/autofill_assistant/content/renderer/autofill_assistant_agent.cc
@@ -22,6 +22,7 @@
 
 #if BUILDFLAG(BUILD_WITH_TFLITE_LIB)
 #include "components/autofill_assistant/content/common/proto/semantic_feature_overrides.pb.h"
+#include "components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils.h"
 #include "components/autofill_assistant/content/renderer/autofill_assistant_model_executor.h"
 #endif  // BUILDFLAG(BUILD_WITH_TFLITE_LIB)
 
@@ -86,8 +87,10 @@
     std::string jsonEncodedSemanticEnums =
         base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
             autofill_assistant::switches::kAutofillAssistantDebugAnnotateDom);
+#if BUILDFLAG(BUILD_WITH_TFLITE_LIB)
     semantic_labels =
         DecodeSemanticPredictionLabelsJson(jsonEncodedSemanticEnums);
+#endif
   }
 }
 
@@ -219,10 +222,11 @@
       }
     }
 
-    if (result && result->first == role &&
-        (result->second == objective || ignore_objective)) {
+    if (result && result->role == role &&
+        (result->objective == objective || ignore_objective)) {
       NodeData node_data;
       node_data.backend_node_id = node_signal.backend_node_id;
+      node_data.used_override = result->used_override;
       nodes.push_back(node_data);
     }
   }
diff --git a/components/autofill_assistant/content/renderer/autofill_assistant_agent.h b/components/autofill_assistant/content/renderer/autofill_assistant_agent.h
index 06962af8..b1e4044 100644
--- a/components/autofill_assistant/content/renderer/autofill_assistant_agent.h
+++ b/components/autofill_assistant/content/renderer/autofill_assistant_agent.h
@@ -12,7 +12,6 @@
 #include "components/autofill_assistant/content/common/autofill_assistant_agent.mojom.h"
 #include "components/autofill_assistant/content/common/autofill_assistant_driver.mojom.h"
 #include "components/autofill_assistant/content/common/node_data.h"
-#include "components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils.h"
 #include "content/public/renderer/render_frame_observer.h"
 #include "mojo/public/cpp/bindings/associated_receiver.h"
 #include "mojo/public/cpp/bindings/associated_remote.h"
@@ -83,6 +82,9 @@
                            const std::u16string& value,
                            bool send_events);
 
+  using SemanticPredictionLabelMap = base::flat_map<int, std::string>;
+  using SemanticLabelsPair =
+      std::pair<SemanticPredictionLabelMap, SemanticPredictionLabelMap>;
   SemanticLabelsPair semantic_labels;
 
   mojo::AssociatedRemote<mojom::AutofillAssistantDriver> driver_;
diff --git a/components/autofill_assistant/content/renderer/autofill_assistant_agent_browsertest.cc b/components/autofill_assistant/content/renderer/autofill_assistant_agent_browsertest.cc
index a548d57..8357414 100644
--- a/components/autofill_assistant/content/renderer/autofill_assistant_agent_browsertest.cc
+++ b/components/autofill_assistant/content/renderer/autofill_assistant_agent_browsertest.cc
@@ -18,6 +18,7 @@
 #include "content/public/renderer/render_frame.h"
 #include "content/public/test/render_view_test.h"
 #include "mojo/public/cpp/bindings/associated_receiver_set.h"
+#include "testing/gmock/include/gmock/gmock-matchers.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
@@ -32,6 +33,7 @@
 
 using ::base::test::RunOnceCallback;
 using ::testing::_;
+using ::testing::Field;
 using ::testing::SizeIs;
 
 constexpr int kDummySemanticRole = 9999;
@@ -107,7 +109,9 @@
   base::MockCallback<base::OnceCallback<void(mojom::NodeDataStatus,
                                              const std::vector<NodeData>&)>>
       callback;
-  EXPECT_CALL(callback, Run(mojom::NodeDataStatus::kSuccess, SizeIs(1)));
+  EXPECT_CALL(callback,
+              Run(mojom::NodeDataStatus::kSuccess,
+                  ElementsAre(Field(&NodeData::used_override, false))));
 
   LoadHTML(R"(
     <div>
@@ -291,7 +295,9 @@
   base::MockCallback<base::OnceCallback<void(mojom::NodeDataStatus,
                                              const std::vector<NodeData>&)>>
       callback;
-  EXPECT_CALL(callback, Run(mojom::NodeDataStatus::kSuccess, SizeIs(1)));
+  EXPECT_CALL(callback,
+              Run(mojom::NodeDataStatus::kSuccess,
+                  ElementsAre(Field(&NodeData::used_override, true))));
 
   autofill_assistant_agent_->GetSemanticNodes(
       kDummySemanticRole, kDummyObjective,
diff --git a/components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils.cc b/components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils.cc
index 2144f16..ee30af96 100644
--- a/components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils.cc
+++ b/components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils.cc
@@ -86,27 +86,30 @@
 std::u16string SemanticPredictionResultToDebugString(
     SemanticPredictionLabelMap roles,
     SemanticPredictionLabelMap objectives,
-    const std::pair<int, int>& result,
+    const ModelExecutorResult& result,
     bool ignore_objective) {
+  int role = result.role;
+  int objective = result.objective;
   if (!roles.empty() || !objectives.empty()) {
     std::string result_label =
-        roles.contains(result.first)
-            ? roles.at(result.first)
-            : "(missing-label) " + base::NumberToString(result.first);
+        roles.contains(role) ? roles.at(role)
+                             : "(missing-label) " + base::NumberToString(role);
     std::string objective_label =
-        objectives.contains(result.second)
-            ? objectives.at(result.second)
-            : "(missing-label) " + base::NumberToString(result.second);
+        objectives.contains(objective)
+            ? objectives.at(objective)
+            : "(missing-label) " + base::NumberToString(objective);
     return base::StrCat(
         {u"{role: ", std::u16string(result_label.begin(), result_label.end()),
          u", objective: ",
          std::u16string(objective_label.begin(), objective_label.end()),
-         (ignore_objective ? u"(ignored)}" : u"}")});
+         (ignore_objective ? u"(ignored)}" : u"}"),
+         (result.used_override ? u"[override]" : u"")});
   }
 
-  return base::StrCat({u"{role: ", base::NumberToString16(result.first),
-                       u", objective: ", base::NumberToString16(result.second),
-                       (ignore_objective ? u"(ignored)}" : u"}")});
+  return base::StrCat({u"{role: ", base::NumberToString16(role),
+                       u", objective: ", base::NumberToString16(objective),
+                       (ignore_objective ? u"(ignored)}" : u"}"),
+                       (result.used_override ? u"[override]" : u"")});
 }
 
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils.h b/components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils.h
index df96538..1ef8ac6 100644
--- a/components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils.h
+++ b/components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils.h
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "base/containers/flat_map.h"
+#include "components/autofill_assistant/content/renderer/autofill_assistant_model_executor_result.h"
 #include "third_party/blink/public/web/modules/autofill_assistant/node_signals.h"
 
 namespace autofill_assistant {
@@ -33,7 +34,7 @@
 std::u16string SemanticPredictionResultToDebugString(
     SemanticPredictionLabelMap roles,
     SemanticPredictionLabelMap objectives,
-    const std::pair<int, int>& result,
+    const ModelExecutorResult& result,
     bool ignore_objective);
 
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils_unittest.cc b/components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils_unittest.cc
index f32b6808..6c5d8cd1 100644
--- a/components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils_unittest.cc
+++ b/components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils_unittest.cc
@@ -11,7 +11,11 @@
 namespace autofill_assistant {
 namespace {
 
-using SemanticLabelsJsonParsingTest = ::testing::Test;
+class SemanticLabelsJsonParsingTest : public ::testing::Test {
+ protected:
+  ModelExecutorResult model_executor_result_ =
+      ModelExecutorResult(47, 7, false);
+};
 
 TEST_F(SemanticLabelsJsonParsingTest, ValidJson) {
   std::string json_input = R"({
@@ -28,7 +32,27 @@
   SemanticLabelsPair labels = DecodeSemanticPredictionLabelsJson(base64_json);
 
   std::u16string debug_string = SemanticPredictionResultToDebugString(
-      labels.first, labels.second, {47, 7}, false);
+      labels.first, labels.second, model_executor_result_, false);
+  EXPECT_EQ(debug_string,
+            std::u16string(expected_output.begin(), expected_output.end()));
+}
+
+TEST_F(SemanticLabelsJsonParsingTest, UseOverrideField) {
+  std::string json_input = R"({
+      "roles": [{"id": 47, "name": "ADDRESS_LINE1"}],
+      "objectives": [{"id": 7, "name": "FILL_DELIVERY_ADDRESS"}]
+    })";
+  std::string expected_output =
+      "{role: ADDRESS_LINE1, objective: FILL_DELIVERY_ADDRESS}[override]";
+
+  // Encode the JSON and add it to the debug DOM annotations switch
+  std::string base64_json;
+  base::Base64Encode(json_input, &base64_json);
+
+  SemanticLabelsPair labels = DecodeSemanticPredictionLabelsJson(base64_json);
+
+  std::u16string debug_string = SemanticPredictionResultToDebugString(
+      labels.first, labels.second, ModelExecutorResult(47, 7, true), false);
   EXPECT_EQ(debug_string,
             std::u16string(expected_output.begin(), expected_output.end()));
 }
@@ -54,7 +78,7 @@
   SemanticLabelsPair labels = DecodeSemanticPredictionLabelsJson(base64_json);
 
   std::u16string debug_string = SemanticPredictionResultToDebugString(
-      labels.first, labels.second, {47, 7}, false);
+      labels.first, labels.second, model_executor_result_, false);
   EXPECT_EQ(debug_string,
             std::u16string(expected_output.begin(), expected_output.end()));
 }
@@ -70,7 +94,7 @@
   SemanticLabelsPair labels = DecodeSemanticPredictionLabelsJson(base64_json);
 
   std::u16string debug_string = SemanticPredictionResultToDebugString(
-      labels.first, labels.second, {47, 7}, false);
+      labels.first, labels.second, model_executor_result_, false);
   EXPECT_EQ(debug_string,
             std::u16string(expected_output.begin(), expected_output.end()));
 }
@@ -90,7 +114,7 @@
   SemanticLabelsPair labels = DecodeSemanticPredictionLabelsJson(base64_json);
 
   std::u16string debug_string = SemanticPredictionResultToDebugString(
-      labels.first, labels.second, {47, 7}, false);
+      labels.first, labels.second, model_executor_result_, false);
   EXPECT_EQ(debug_string,
             std::u16string(expected_output.begin(), expected_output.end()));
 }
@@ -110,7 +134,7 @@
   SemanticLabelsPair labels = DecodeSemanticPredictionLabelsJson(base64_json);
 
   std::u16string debug_string = SemanticPredictionResultToDebugString(
-      labels.first, labels.second, {47, 7}, false);
+      labels.first, labels.second, model_executor_result_, false);
   EXPECT_EQ(debug_string,
             std::u16string(expected_output.begin(), expected_output.end()));
 }
@@ -129,7 +153,7 @@
   SemanticLabelsPair labels = DecodeSemanticPredictionLabelsJson(base64_json);
 
   std::u16string debug_string = SemanticPredictionResultToDebugString(
-      labels.first, labels.second, {47, 7}, false);
+      labels.first, labels.second, model_executor_result_, false);
   EXPECT_EQ(debug_string,
             std::u16string(expected_output.begin(), expected_output.end()));
 }
@@ -149,7 +173,7 @@
   SemanticLabelsPair labels = DecodeSemanticPredictionLabelsJson(base64_json);
 
   std::u16string debug_string = SemanticPredictionResultToDebugString(
-      labels.first, labels.second, {47, 7}, false);
+      labels.first, labels.second, model_executor_result_, false);
   EXPECT_EQ(debug_string,
             std::u16string(expected_output.begin(), expected_output.end()));
 }
@@ -169,7 +193,7 @@
   SemanticLabelsPair labels = DecodeSemanticPredictionLabelsJson(base64_json);
 
   std::u16string debug_string = SemanticPredictionResultToDebugString(
-      labels.first, labels.second, {47, 7}, false);
+      labels.first, labels.second, model_executor_result_, false);
   EXPECT_EQ(debug_string,
             std::u16string(expected_output.begin(), expected_output.end()));
 }
@@ -185,7 +209,7 @@
   SemanticLabelsPair labels = DecodeSemanticPredictionLabelsJson(base64_json);
 
   std::u16string debug_string = SemanticPredictionResultToDebugString(
-      labels.first, labels.second, {47, 7}, false);
+      labels.first, labels.second, model_executor_result_, false);
   EXPECT_EQ(debug_string,
             std::u16string(expected_output.begin(), expected_output.end()));
 }
diff --git a/components/autofill_assistant/content/renderer/autofill_assistant_model_executor.cc b/components/autofill_assistant/content/renderer/autofill_assistant_model_executor.cc
index 496d218ac..8b3a60b 100644
--- a/components/autofill_assistant/content/renderer/autofill_assistant_model_executor.cc
+++ b/components/autofill_assistant/content/renderer/autofill_assistant_model_executor.cc
@@ -6,6 +6,7 @@
 
 #include <ostream>
 
+#include "autofill_assistant_model_executor.h"
 #include "base/command_line.h"
 #include "base/i18n/case_conversion.h"
 #include "base/no_destructor.h"
@@ -112,7 +113,7 @@
       std::make_unique<ExecutionTask>(std::move(tflite_engine), this);
 }
 
-absl::optional<std::pair<int, int>>
+absl::optional<ModelExecutorResult>
 AutofillAssistantModelExecutor::ExecuteModelWithInput(
     const blink::AutofillAssistantNodeSignals& node_signals) {
   if (!execution_task_) {
@@ -252,7 +253,7 @@
   return true;
 }
 
-absl::optional<std::pair<int, int>> AutofillAssistantModelExecutor::Postprocess(
+absl::optional<ModelExecutorResult> AutofillAssistantModelExecutor::Postprocess(
     const std::vector<const TfLiteTensor*>& output_tensors) {
   // Check if we have an override for this execution and return that instead.
   if (overrides_result_) {
@@ -262,7 +263,8 @@
               << ", objective: " << overrides_result_->second << ")";
     }
     // Cleanup the result in case this executor is reused.
-    std::pair<int, int> result = *overrides_result_;
+    ModelExecutorResult result(overrides_result_->first,
+                               overrides_result_->second, true);
     overrides_result_.reset();
     return result;
   }
@@ -296,7 +298,7 @@
   int semantic_role =
       model_metadata_.output().semantic_role().classes(index_of_best_role);
   if (semantic_role == 0) {
-    return std::pair<int, int>(semantic_role, 0);
+    return ModelExecutorResult(/*r=*/0, /*o=*/0, /*with_override=*/false);
   }
 
   int block_index;
@@ -308,7 +310,8 @@
     return absl::nullopt;
   }
 
-  return std::pair<int, int>(semantic_role, objective);
+  ModelExecutorResult result(semantic_role, objective, false);
+  return result;
 }
 
 void AutofillAssistantModelExecutor::Tokenize(
diff --git a/components/autofill_assistant/content/renderer/autofill_assistant_model_executor.h b/components/autofill_assistant/content/renderer/autofill_assistant_model_executor.h
index 7e8822e..88d662b 100644
--- a/components/autofill_assistant/content/renderer/autofill_assistant_model_executor.h
+++ b/components/autofill_assistant/content/renderer/autofill_assistant_model_executor.h
@@ -11,6 +11,7 @@
 
 #include "base/files/file.h"
 #include "base/files/memory_mapped_file.h"
+#include "components/autofill_assistant/content/renderer/autofill_assistant_model_executor_result.h"
 #include "components/autofill_assistant/content/renderer/model_metadata.pb.h"
 #include "components/optimization_guide/core/base_model_executor.h"
 #include "components/optimization_guide/core/base_model_executor_helpers.h"
@@ -27,11 +28,11 @@
 // node signals.
 class AutofillAssistantModelExecutor
     : public optimization_guide::BaseModelExecutor<
-          std::pair<int, int>,
+          ModelExecutorResult,
           const blink::AutofillAssistantNodeSignals&> {
  public:
   using ExecutionTask = optimization_guide::GenericModelExecutionTask<
-      std::pair<int, int>,
+      ModelExecutorResult,
       const blink::AutofillAssistantNodeSignals&>;
   using SparseVector = std::vector<std::pair<std::pair<int, int>, int>>;
   using SparseMap = base::flat_map<std::pair<int, int>, int>;
@@ -49,7 +50,7 @@
   bool InitializeModelFromFile(base::File model_file);
 
   // Execute the model with the given input.
-  absl::optional<std::pair<int, int>> ExecuteModelWithInput(
+  absl::optional<ModelExecutorResult> ExecuteModelWithInput(
       const blink::AutofillAssistantNodeSignals& node_signals);
 
  protected:
@@ -57,7 +58,7 @@
   bool Preprocess(
       const std::vector<TfLiteTensor*>& input_tensors,
       const blink::AutofillAssistantNodeSignals& node_signals) override;
-  absl::optional<std::pair<int, int>> Postprocess(
+  absl::optional<ModelExecutorResult> Postprocess(
       const std::vector<const TfLiteTensor*>& output_tensors) override;
 
  private:
diff --git a/components/autofill_assistant/content/renderer/autofill_assistant_model_executor_result.h b/components/autofill_assistant/content/renderer/autofill_assistant_model_executor_result.h
new file mode 100644
index 0000000..42c40fd
--- /dev/null
+++ b/components/autofill_assistant/content/renderer/autofill_assistant_model_executor_result.h
@@ -0,0 +1,26 @@
+// 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.
+
+#ifndef COMPONENTS_AUTOFILL_ASSISTANT_CONTENT_RENDERER_AUTOFILL_ASSISTANT_MODEL_EXECUTOR_RESULT_H_
+#define COMPONENTS_AUTOFILL_ASSISTANT_CONTENT_RENDERER_AUTOFILL_ASSISTANT_MODEL_EXECUTOR_RESULT_H_
+
+namespace autofill_assistant {
+
+// Result used to communicated model execution results between interested
+// parties.
+struct ModelExecutorResult {
+  ModelExecutorResult() = default;
+  ModelExecutorResult(int r, int o, bool with_override)
+      : role(r), objective(o), used_override(with_override) {}
+
+  // Role and objective pair.
+  int role = 0;
+  int objective = 0;
+  // Whether this result came from an override.
+  bool used_override = false;
+};
+
+}  // namespace autofill_assistant
+
+#endif  // COMPONENTS_AUTOFILL_ASSISTANT_CONTENT_RENDERER_AUTOFILL_ASSISTANT_MODEL_EXECUTOR_RESULT_H_
diff --git a/components/autofill_assistant/content/renderer/autofill_assistant_model_executor_unittest.cc b/components/autofill_assistant/content/renderer/autofill_assistant_model_executor_unittest.cc
index 1212e00..862620e 100644
--- a/components/autofill_assistant/content/renderer/autofill_assistant_model_executor_unittest.cc
+++ b/components/autofill_assistant/content/renderer/autofill_assistant_model_executor_unittest.cc
@@ -101,8 +101,8 @@
 
   auto result = model_executor_.ExecuteModelWithInput(node_signals);
   ASSERT_TRUE(result.has_value());
-  EXPECT_EQ(result->first, 47 /* ADDRESS_LINE1 */);
-  EXPECT_EQ(result->second, 7 /* FILL_DELIVERY_ADDRESS */);
+  EXPECT_EQ(result->role, 47 /* ADDRESS_LINE1 */);
+  EXPECT_EQ(result->objective, 7 /* FILL_DELIVERY_ADDRESS */);
 }
 
 TEST_F(AutofillAssistantModelExecutorTest, OverridesMatch) {
@@ -119,8 +119,9 @@
 
   auto result = model_executor.ExecuteModelWithInput(node_signals);
   ASSERT_TRUE(result.has_value());
-  EXPECT_EQ(result->first, 9999);
-  EXPECT_EQ(result->second, 1111);
+  EXPECT_EQ(result->role, 9999);
+  EXPECT_EQ(result->objective, 1111);
+  EXPECT_TRUE(result->used_override);
 }
 
 TEST_F(AutofillAssistantModelExecutorTest, OverridesNoMatch) {
@@ -135,8 +136,9 @@
 
   auto result = model_executor.ExecuteModelWithInput(node_signals);
   ASSERT_TRUE(result.has_value());
-  EXPECT_NE(result->first, 9999);
-  EXPECT_NE(result->second, 1111);
+  EXPECT_NE(result->role, 9999);
+  EXPECT_NE(result->objective, 1111);
+  EXPECT_FALSE(result->used_override);
 }
 
 TEST_F(AutofillAssistantModelExecutorTest, OverridesResultNotReused) {
@@ -153,8 +155,9 @@
 
     auto result = model_executor.ExecuteModelWithInput(node_signals);
     ASSERT_TRUE(result.has_value());
-    EXPECT_EQ(result->first, 9999);
-    EXPECT_EQ(result->second, 1111);
+    EXPECT_EQ(result->role, 9999);
+    EXPECT_EQ(result->objective, 1111);
+    EXPECT_TRUE(result->used_override);
   }
 
   // We expect the internal overrides result from the previous execution to have
@@ -166,8 +169,9 @@
 
     auto result = model_executor.ExecuteModelWithInput(node_signals);
     ASSERT_TRUE(result.has_value());
-    EXPECT_NE(result->first, 9999);
-    EXPECT_NE(result->second, 1111);
+    EXPECT_NE(result->role, 9999);
+    EXPECT_NE(result->objective, 1111);
+    EXPECT_FALSE(result->used_override);
   }
 }
 
diff --git a/components/cast_streaming/renderer/frame_injecting_demuxer.cc b/components/cast_streaming/renderer/frame_injecting_demuxer.cc
index 7d51434b..5ff5ded 100644
--- a/components/cast_streaming/renderer/frame_injecting_demuxer.cc
+++ b/components/cast_streaming/renderer/frame_injecting_demuxer.cc
@@ -264,7 +264,7 @@
 
 FrameInjectingDemuxer::FrameInjectingDemuxer(
     DemuxerConnector* demuxer_connector,
-    scoped_refptr<base::SingleThreadTaskRunner> media_task_runner)
+    scoped_refptr<base::SequencedTaskRunner> media_task_runner)
     : media_task_runner_(std::move(media_task_runner)),
       original_task_runner_(base::SequencedTaskRunnerHandle::Get()),
       demuxer_connector_(demuxer_connector),
@@ -287,7 +287,7 @@
     mojom::AudioStreamInitializationInfoPtr audio_stream_info,
     mojom::VideoStreamInitializationInfoPtr video_stream_info) {
   DVLOG(1) << __func__;
-  DCHECK(!media_task_runner_->BelongsToCurrentThread());
+  DCHECK(!media_task_runner_->RunsTasksInCurrentSequence());
 
   media_task_runner_->PostTask(
       FROM_HERE,
@@ -300,7 +300,7 @@
     mojom::AudioStreamInitializationInfoPtr audio_stream_info,
     mojom::VideoStreamInitializationInfoPtr video_stream_info) {
   DVLOG(1) << __func__;
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(initialized_cb_);
 
   if (!audio_stream_info && !video_stream_info) {
@@ -342,7 +342,7 @@
 
 std::vector<media::DemuxerStream*> FrameInjectingDemuxer::GetAllStreams() {
   DVLOG(1) << __func__;
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   std::vector<media::DemuxerStream*> streams;
   if (video_stream_)
@@ -360,7 +360,7 @@
     media::DemuxerHost* host,
     media::PipelineStatusCallback status_cb) {
   DVLOG(1) << __func__;
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   host_ = host;
 
   // Live streams have infinite duration.
@@ -375,7 +375,7 @@
 
 void FrameInjectingDemuxer::AbortPendingReads() {
   DVLOG(2) << __func__;
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   if (audio_stream_)
     audio_stream_->AbortPendingRead();
@@ -397,7 +397,7 @@
 
 void FrameInjectingDemuxer::Stop() {
   DVLOG(1) << __func__;
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   if (audio_stream_)
     audio_stream_.reset();
diff --git a/components/cast_streaming/renderer/frame_injecting_demuxer.h b/components/cast_streaming/renderer/frame_injecting_demuxer.h
index 2fdcee9..25f1ca9 100644
--- a/components/cast_streaming/renderer/frame_injecting_demuxer.h
+++ b/components/cast_streaming/renderer/frame_injecting_demuxer.h
@@ -11,10 +11,6 @@
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
-namespace base {
-class SingleThreadTaskRunner;
-}
-
 namespace cast_streaming {
 
 class FrameInjectingAudioDemuxerStream;
@@ -32,7 +28,7 @@
  public:
   FrameInjectingDemuxer(
       DemuxerConnector* demuxer_connector,
-      scoped_refptr<base::SingleThreadTaskRunner> media_task_runner);
+      scoped_refptr<base::SequencedTaskRunner> media_task_runner);
   ~FrameInjectingDemuxer() override;
 
   FrameInjectingDemuxer(const FrameInjectingDemuxer&) = delete;
@@ -77,7 +73,7 @@
   // OnStreamInitializationComplete().
   int pending_stream_initialization_callbacks_ = 0;
 
-  scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+  scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
   scoped_refptr<base::SequencedTaskRunner> original_task_runner_;
   media::DemuxerHost* host_ = nullptr;
   std::unique_ptr<FrameInjectingAudioDemuxerStream> audio_stream_;
diff --git a/components/cast_streaming/renderer/playback_command_forwarding_renderer.cc b/components/cast_streaming/renderer/playback_command_forwarding_renderer.cc
index b276199..da36781 100644
--- a/components/cast_streaming/renderer/playback_command_forwarding_renderer.cc
+++ b/components/cast_streaming/renderer/playback_command_forwarding_renderer.cc
@@ -27,7 +27,7 @@
   RendererCommandForwarder(
       PlaybackCommandForwardingRenderer* owning_renderer,
       mojo::PendingReceiver<media::mojom::Renderer> playback_controller,
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+      scoped_refptr<base::SequencedTaskRunner> task_runner)
       : owning_renderer_(owning_renderer),
         playback_controller_(this, std::move(playback_controller)) {
     DCHECK(owning_renderer_);
@@ -81,7 +81,7 @@
 
 PlaybackCommandForwardingRenderer::PlaybackCommandForwardingRenderer(
     std::unique_ptr<media::Renderer> renderer,
-    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    scoped_refptr<base::SequencedTaskRunner> task_runner,
     mojo::PendingReceiver<media::mojom::Renderer> pending_renderer_controls)
     : real_renderer_(std::move(renderer)),
       pending_renderer_controls_(std::move(pending_renderer_controls)),
@@ -89,7 +89,6 @@
       weak_factory_(this) {
   DCHECK(real_renderer_);
   DCHECK(pending_renderer_controls_);
-
   InitializeSendTimestampUpdateCaller();
 }
 
@@ -126,11 +125,11 @@
 void PlaybackCommandForwardingRenderer::Flush(base::OnceClosure flush_cb) {}
 
 void PlaybackCommandForwardingRenderer::StartPlayingFrom(base::TimeDelta time) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 }
 
 void PlaybackCommandForwardingRenderer::SetPlaybackRate(double playback_rate) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 }
 
 void PlaybackCommandForwardingRenderer::SetVolume(float volume) {}
@@ -171,7 +170,7 @@
   // over the mojo pipe here
   DCHECK(!streams || streams.value().empty());
 
-  if (!task_runner_->BelongsToCurrentThread()) {
+  if (!task_runner_->RunsTasksInCurrentSequence()) {
     task_runner_->PostTask(
         FROM_HERE,
         base::BindOnce(
@@ -190,7 +189,7 @@
 
 void PlaybackCommandForwardingRenderer::MojoRendererFlush(
     media::mojom::Renderer::FlushCallback callback) {
-  if (!task_runner_->BelongsToCurrentThread()) {
+  if (!task_runner_->RunsTasksInCurrentSequence()) {
     task_runner_->PostTask(
         FROM_HERE,
         base::BindOnce(&PlaybackCommandForwardingRenderer::MojoRendererFlush,
@@ -203,7 +202,7 @@
 
 void PlaybackCommandForwardingRenderer::MojoRendererStartPlayingFrom(
     ::base::TimeDelta time) {
-  if (!task_runner_->BelongsToCurrentThread()) {
+  if (!task_runner_->RunsTasksInCurrentSequence()) {
     task_runner_->PostTask(
         FROM_HERE,
         base::BindOnce(
@@ -217,7 +216,7 @@
 
 void PlaybackCommandForwardingRenderer::MojoRendererSetPlaybackRate(
     double playback_rate) {
-  if (!task_runner_->BelongsToCurrentThread()) {
+  if (!task_runner_->RunsTasksInCurrentSequence()) {
     task_runner_->PostTask(
         FROM_HERE,
         base::BindOnce(
@@ -230,7 +229,7 @@
 }
 
 void PlaybackCommandForwardingRenderer::MojoRendererSetVolume(float volume) {
-  if (!task_runner_->BelongsToCurrentThread()) {
+  if (!task_runner_->RunsTasksInCurrentSequence()) {
     task_runner_->PostTask(
         FROM_HERE,
         base::BindOnce(
@@ -261,7 +260,7 @@
 }
 
 void PlaybackCommandForwardingRenderer::OnEnded() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   if (remote_renderer_client_)
     remote_renderer_client_->OnEnded();
@@ -271,7 +270,7 @@
 
 void PlaybackCommandForwardingRenderer::OnStatisticsUpdate(
     const media::PipelineStatistics& stats) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   if (remote_renderer_client_)
     remote_renderer_client_->OnStatisticsUpdate(stats);
@@ -282,7 +281,7 @@
 void PlaybackCommandForwardingRenderer::OnBufferingStateChange(
     media::BufferingState state,
     media::BufferingStateChangeReason reason) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   if (remote_renderer_client_)
     remote_renderer_client_->OnBufferingStateChange(state, reason);
@@ -291,7 +290,7 @@
 }
 
 void PlaybackCommandForwardingRenderer::OnWaiting(media::WaitingReason reason) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   if (remote_renderer_client_)
     remote_renderer_client_->OnWaiting(reason);
@@ -301,7 +300,7 @@
 
 void PlaybackCommandForwardingRenderer::OnAudioConfigChange(
     const media::AudioDecoderConfig& config) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   if (remote_renderer_client_)
     remote_renderer_client_->OnAudioConfigChange(config);
@@ -311,7 +310,7 @@
 
 void PlaybackCommandForwardingRenderer::OnVideoConfigChange(
     const media::VideoDecoderConfig& config) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   if (remote_renderer_client_)
     remote_renderer_client_->OnVideoConfigChange(config);
@@ -321,7 +320,7 @@
 
 void PlaybackCommandForwardingRenderer::OnVideoNaturalSizeChange(
     const gfx::Size& size) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   if (remote_renderer_client_)
     remote_renderer_client_->OnVideoNaturalSizeChange(size);
@@ -330,7 +329,7 @@
 }
 
 void PlaybackCommandForwardingRenderer::OnVideoOpacityChange(bool opaque) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   if (remote_renderer_client_)
     remote_renderer_client_->OnVideoOpacityChange(opaque);
@@ -340,7 +339,7 @@
 
 void PlaybackCommandForwardingRenderer::OnVideoFrameRateChange(
     absl::optional<int> fps) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   // media::mojom::RendererClient does not support this call.
   if (upstream_renderer_client_)
@@ -348,7 +347,7 @@
 }
 
 void PlaybackCommandForwardingRenderer::SendTimestampUpdate() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   if (!remote_renderer_client_) {
     return;
@@ -362,7 +361,7 @@
 }
 
 void PlaybackCommandForwardingRenderer::InitializeSendTimestampUpdateCaller() {
-  if (!task_runner_->BelongsToCurrentThread()) {
+  if (!task_runner_->RunsTasksInCurrentSequence()) {
     task_runner_->PostTask(
         FROM_HERE, base::BindOnce(&PlaybackCommandForwardingRenderer::
                                       InitializeSendTimestampUpdateCaller,
@@ -380,7 +379,7 @@
 }
 
 void PlaybackCommandForwardingRenderer::OnMojoDisconnect() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   OnError(media::PIPELINE_ERROR_DISCONNECTED);
   real_renderer_.reset();
diff --git a/components/cast_streaming/renderer/playback_command_forwarding_renderer.h b/components/cast_streaming/renderer/playback_command_forwarding_renderer.h
index eba2a17..c8d521cb 100644
--- a/components/cast_streaming/renderer/playback_command_forwarding_renderer.h
+++ b/components/cast_streaming/renderer/playback_command_forwarding_renderer.h
@@ -8,6 +8,7 @@
 #include <memory>
 
 #include "base/memory/weak_ptr.h"
+#include "base/task/sequenced_task_runner.h"
 #include "media/base/renderer.h"
 #include "media/base/renderer_client.h"
 #include "media/mojo/mojom/renderer.mojom.h"
@@ -29,7 +30,7 @@
   // playback commands to this instance.
   PlaybackCommandForwardingRenderer(
       std::unique_ptr<media::Renderer> renderer,
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+      scoped_refptr<base::SequencedTaskRunner> task_runner,
       mojo::PendingReceiver<media::mojom::Renderer> pending_rederer_controls);
   PlaybackCommandForwardingRenderer(const PlaybackCommandForwardingRenderer&) =
       delete;
@@ -125,7 +126,7 @@
   mojo::PendingReceiver<media::mojom::Renderer> pending_renderer_controls_;
 
   // Task runner on which all mojo callbacks will be run.
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+  scoped_refptr<base::SequencedTaskRunner> task_runner_;
 
   // Created as part of OnRealRendererInitializationComplete().
   std::unique_ptr<media::mojom::Renderer> playback_controller_;
diff --git a/components/cast_streaming/renderer/playback_command_forwarding_renderer_factory.cc b/components/cast_streaming/renderer/playback_command_forwarding_renderer_factory.cc
index 4439fb3..36cb1de 100644
--- a/components/cast_streaming/renderer/playback_command_forwarding_renderer_factory.cc
+++ b/components/cast_streaming/renderer/playback_command_forwarding_renderer_factory.cc
@@ -26,7 +26,7 @@
 
 std::unique_ptr<media::Renderer>
 PlaybackCommandForwardingRendererFactory::CreateRenderer(
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
     const scoped_refptr<base::TaskRunner>& worker_task_runner,
     media::AudioRendererSink* audio_renderer_sink,
     media::VideoRendererSink* video_renderer_sink,
diff --git a/components/cast_streaming/renderer/playback_command_forwarding_renderer_factory.h b/components/cast_streaming/renderer/playback_command_forwarding_renderer_factory.h
index 9655acf..4b55d6e 100644
--- a/components/cast_streaming/renderer/playback_command_forwarding_renderer_factory.h
+++ b/components/cast_streaming/renderer/playback_command_forwarding_renderer_factory.h
@@ -69,7 +69,7 @@
   // Wraps |real_renderer_factory_->CreateRenderer()|'s results with a
   // PlaybackCommandForwardingRenderer instance.
   std::unique_ptr<media::Renderer> CreateRenderer(
-      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+      const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
       const scoped_refptr<base::TaskRunner>& worker_task_runner,
       media::AudioRendererSink* audio_renderer_sink,
       media::VideoRendererSink* video_renderer_sink,
diff --git a/components/cast_streaming/renderer/public/resource_provider.h b/components/cast_streaming/renderer/public/resource_provider.h
index 2556a71..87d1a5d 100644
--- a/components/cast_streaming/renderer/public/resource_provider.h
+++ b/components/cast_streaming/renderer/public/resource_provider.h
@@ -16,10 +16,6 @@
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "url/gurl.h"
 
-namespace base {
-class SingleThreadTaskRunner;
-}  // namespace base
-
 namespace media {
 class Demuxer;
 }  // namespace media
@@ -58,7 +54,7 @@
   // CastStreamingDemuxer instance in the case of a match.
   virtual std::unique_ptr<media::Demuxer> MaybeGetDemuxerOverride(
       const GURL& url,
-      scoped_refptr<base::SingleThreadTaskRunner> media_task_runner) = 0;
+      scoped_refptr<base::SequencedTaskRunner> media_task_runner) = 0;
 
   // Gets the receiver for this instance. To be used by the renderer-process
   // PlaybackCommandForwardingRenderer to receive playback commands from the
diff --git a/components/cast_streaming/renderer/resource_provider_impl.cc b/components/cast_streaming/renderer/resource_provider_impl.cc
index 6ee244b..d3ca1504 100644
--- a/components/cast_streaming/renderer/resource_provider_impl.cc
+++ b/components/cast_streaming/renderer/resource_provider_impl.cc
@@ -60,7 +60,7 @@
 
 std::unique_ptr<media::Demuxer> ResourceProviderImpl::MaybeGetDemuxerOverride(
     const GURL& url,
-    scoped_refptr<base::SingleThreadTaskRunner> media_task_runner) {
+    scoped_refptr<base::SequencedTaskRunner> media_task_runner) {
   // Do not create a FrameInjectingDemuxer if the Cast Streaming MessagePort
   // was not set in the browser process. This will manifest as an unbound
   // DemuxerConnector object in the renderer process.
diff --git a/components/cast_streaming/renderer/resource_provider_impl.h b/components/cast_streaming/renderer/resource_provider_impl.h
index 81a2bc5..dbbc8b81 100644
--- a/components/cast_streaming/renderer/resource_provider_impl.h
+++ b/components/cast_streaming/renderer/resource_provider_impl.h
@@ -12,6 +12,7 @@
 #include "base/callback_forward.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
+#include "base/task/sequenced_task_runner.h"
 #include "components/cast_streaming/public/mojom/demuxer_connector.mojom.h"
 #include "components/cast_streaming/public/mojom/renderer_controller.mojom.h"
 #include "components/cast_streaming/renderer/demuxer_connector.h"
@@ -22,10 +23,6 @@
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "url/gurl.h"
 
-namespace base {
-class SingleThreadTaskRunner;
-}
-
 namespace media {
 class Demuxer;
 }  // namespace media
@@ -85,7 +82,7 @@
   ReceiverBinder<mojom::DemuxerConnector> GetDemuxerConnectorBinder() override;
   std::unique_ptr<media::Demuxer> MaybeGetDemuxerOverride(
       const GURL& url,
-      scoped_refptr<base::SingleThreadTaskRunner> media_task_runner) override;
+      scoped_refptr<base::SequencedTaskRunner> media_task_runner) override;
   mojo::PendingReceiver<media::mojom::Renderer> GetRendererCommandReceiver()
       override;
 
diff --git a/components/feed/core/common/pref_names.cc b/components/feed/core/common/pref_names.cc
index 095f0412..71e4c51 100644
--- a/components/feed/core/common/pref_names.cc
+++ b/components/feed/core/common/pref_names.cc
@@ -47,6 +47,8 @@
 const char kLastSeenFeedType[] = "feedv2.last_seen_feed_type";
 const char kFeedOnDeviceUserActionsCollector[] = "feed.user_actions_collection";
 const char kInfoCardStates[] = "feed.info_card_states";
+const char kHasSeenWebFeed[] = "webfeed.has_seen_feed";
+const char kLastBadgeAnimationTime[] = "webfeed.last_badge_animation_time";
 
 }  // namespace prefs
 
@@ -92,6 +94,9 @@
   registry->RegisterListPref(feed::prefs::kFeedOnDeviceUserActionsCollector,
                              PrefRegistry::LOSSY_PREF);
   registry->RegisterDictionaryPref(feed::prefs::kInfoCardStates, 0);
+  registry->RegisterBooleanPref(feed::prefs::kHasSeenWebFeed, false);
+  registry->RegisterTimePref(feed::prefs::kLastBadgeAnimationTime,
+                             base::Time());
 
 #if BUILDFLAG(IS_IOS)
   registry->RegisterBooleanPref(feed::prefs::kLastFetchHadLoggingEnabled,
diff --git a/components/feed/core/common/pref_names.h b/components/feed/core/common/pref_names.h
index 2528276c..538b3054 100644
--- a/components/feed/core/common/pref_names.h
+++ b/components/feed/core/common/pref_names.h
@@ -84,6 +84,10 @@
 extern const char kFeedOnDeviceUserActionsCollector[];
 // The pref name for the keys of the info cards.
 extern const char kInfoCardStates[];
+// The pref name for whether the user has opened/seen web feed at least once.
+extern const char kHasSeenWebFeed[];
+// The pref name for when the user last saw badge animation for web feed.
+extern const char kLastBadgeAnimationTime[];
 
 }  // namespace prefs
 
diff --git a/components/feedback/redaction_tool.cc b/components/feedback/redaction_tool.cc
index 23bd020..60cd1b5f 100644
--- a/components/feedback/redaction_tool.cc
+++ b/components/feedback/redaction_tool.cc
@@ -54,7 +54,18 @@
      PIIType::kLocationInfo},
 
     // Android. Must run first since this expression matches the replacement.
-    {"SSID", "(?i-s)(\\SSID: ['\"]??)(.+)(['\"]??)", PIIType::kSSID},
+    //
+    // If we don't get helpful delimiters like a single/double quote, then we
+    // can only try our best and take out the next 32 characters, the max length
+    // of a SSID. Require at least one non-quote character though so we skip
+    // over the quoted SSIDs (which the following patterns will catch and
+    // redact).
+    {"SSID", "(?i-s)(\\bSSID: )([^'\"]{1,32})(.*)", PIIType::kSSID},
+    // Replace any SSID inside quotes.
+    {"SSID", "(?i-s)(\\bSSID: ['\"])(.+)(['\"])", PIIType::kSSID},
+    // Special WifiNetworkSpecifier#toString.
+    {"SSID", "(?i-s)(\\bSSID Match pattern=[^ ]*\\s?)(.+)(\\})",
+     PIIType::kSSID},
 
     // wpa_supplicant
     {"SSID", "(?i-s)(\\bssid[= ]')(.+)(')", PIIType::kSSID},
diff --git a/components/feedback/redaction_tool_unittest.cc b/components/feedback/redaction_tool_unittest.cc
index 960139d1..9fb87ed 100644
--- a/components/feedback/redaction_tool_unittest.cc
+++ b/components/feedback/redaction_tool_unittest.cc
@@ -368,15 +368,27 @@
             RedactCustomPatterns("ssid=\"LittleTsunami\""));
   EXPECT_EQ("* SSID=<SSID: 5>", RedactCustomPatterns("* SSID=agnagna"));
 
-  EXPECT_EQ("Specifier: <ArcNetworkFactory#1> SSID: <SSID: 6>",
+  EXPECT_EQ("Specifier: <ArcNetworkFactory#1> SSID: \"<SSID: 6>\" foo",
             RedactCustomPatterns(
-                "Specifier: <ArcNetworkFactory#1> SSID: \"GoogleGuest\""));
-  EXPECT_EQ("Specifier: <ArcNetworkFactory#1> SSID: <SSID: 7>",
+                "Specifier: <ArcNetworkFactory#1> SSID: \"GoogleGuest1\" foo"));
+  EXPECT_EQ("Specifier: <ArcNetworkFactory#1> SSID: '<SSID: 7>' foo",
             RedactCustomPatterns(
-                "Specifier: <ArcNetworkFactory#1> SSID: 'GoogleGuest'"));
+                "Specifier: <ArcNetworkFactory#1> SSID: 'GoogleGuest2' foo"));
   EXPECT_EQ("Specifier: <ArcNetworkFactory#1> SSID: <SSID: 8>",
             RedactCustomPatterns(
-                "Specifier: <ArcNetworkFactory#1> SSID: GoogleGuest"));
+                "Specifier: <ArcNetworkFactory#1> SSID: GoogleGuest3"));
+  EXPECT_EQ(
+      "Specifier: <ArcNetworkFactory#1> SSID: <SSID: 9>",
+      RedactCustomPatterns(
+          "Specifier: <ArcNetworkFactory#1> SSID: less than 32 characters"));
+  EXPECT_EQ("Specifier: <ArcNetworkFactory#1> SSID: <SSID: 10>foo",
+            RedactCustomPatterns("Specifier: <ArcNetworkFactory#1> SSID: this "
+                                 "line is 32 characters long!foo"));
+  EXPECT_EQ(
+      "<WifiNetworkSpecifier [, SSID Match pattern=PatternMatcher{LITERAL: "
+      "<SSID: 11>}, ...]",
+      RedactCustomPatterns("<WifiNetworkSpecifier [, SSID Match "
+                           "pattern=PatternMatcher{LITERAL: Google-A}, ...]"));
 
   EXPECT_EQ("SerialNumber: <Serial: 1>",
             RedactCustomPatterns("SerialNumber: 1217D7EF"));
diff --git a/components/js_injection/browser/js_to_browser_messaging.cc b/components/js_injection/browser/js_to_browser_messaging.cc
index d32c1ab4..679a3b9 100644
--- a/components/js_injection/browser/js_to_browser_messaging.cc
+++ b/components/js_injection/browser/js_to_browser_messaging.cc
@@ -10,6 +10,7 @@
 #include "components/js_injection/browser/web_message_host.h"
 #include "components/js_injection/browser/web_message_host_factory.h"
 #include "components/js_injection/browser/web_message_reply_proxy.h"
+#include "components/js_injection/common/web_message.h"
 #include "content/public/browser/disallow_activation_reason.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/web_contents.h"
@@ -50,7 +51,9 @@
 
   // WebMessageReplyProxy:
   void PostWebMessage(std::unique_ptr<WebMessage> message) override {
-    java_to_js_messaging_->OnPostMessage(message->message);
+    JsWebMessage js_message;
+    js_message.string = std::move(message->message);
+    java_to_js_messaging_->OnPostMessage(std::move(js_message));
   }
   bool IsInBackForwardCache() override {
     return render_frame_host_->GetLifecycleState() ==
@@ -82,7 +85,7 @@
 }
 
 void JsToBrowserMessaging::PostMessage(
-    const std::u16string& message,
+    JsWebMessage message,
     std::vector<blink::MessagePortDescriptor> ports) {
   DCHECK(render_frame_host_);
 
@@ -131,7 +134,7 @@
             web_contents->GetPrimaryMainFrame() == render_frame_host_);
 #endif
   std::unique_ptr<WebMessage> web_message = std::make_unique<WebMessage>();
-  web_message->message = message;
+  web_message->message = std::move(message.string);
   web_message->ports = std::move(ports);
   host_->OnPostMessage(std::move(web_message));
 }
diff --git a/components/js_injection/browser/js_to_browser_messaging.h b/components/js_injection/browser/js_to_browser_messaging.h
index 5f51503f..8bffb41 100644
--- a/components/js_injection/browser/js_to_browser_messaging.h
+++ b/components/js_injection/browser/js_to_browser_messaging.h
@@ -24,6 +24,7 @@
 
 namespace js_injection {
 
+struct JsWebMessage;
 class WebMessageHost;
 class WebMessageHostFactory;
 
@@ -47,7 +48,7 @@
   void OnBackForwardCacheStateChanged();
 
   // mojom::JsToBrowserMessaging implementation.
-  void PostMessage(const std::u16string& message,
+  void PostMessage(JsWebMessage message,
                    std::vector<blink::MessagePortDescriptor> ports) override;
   void SetBrowserToJsMessaging(
       mojo::PendingAssociatedRemote<mojom::BrowserToJsMessaging>
diff --git a/components/js_injection/common/BUILD.gn b/components/js_injection/common/BUILD.gn
index e42923c..6dfec19 100644
--- a/components/js_injection/common/BUILD.gn
+++ b/components/js_injection/common/BUILD.gn
@@ -35,6 +35,20 @@
       traits_sources = [ "origin_matcher_mojom_traits.cc" ]
       traits_public_deps = [ ":common" ]
     },
+    {
+      types = [
+        {
+          mojom = "js_injection.mojom.JsWebMessage"
+          cpp = "::js_injection::JsWebMessage"
+          move_only = true
+        },
+      ]
+      traits_headers = [
+        "web_message.h",
+        "web_message_mojom_traits.h",
+      ]
+      traits_sources = [ "web_message_mojom_traits.cc" ]
+    },
   ]
   overridden_deps = [ "//third_party/blink/public/mojom:mojom_core" ]
   component_deps = [ "//third_party/blink/public/common" ]
@@ -46,6 +60,7 @@
     "origin_matcher.cc",
     "origin_matcher_internal.cc",
     "origin_matcher_internal.h",
+    "web_message.cc",
   ]
   deps = [
     "//base",
diff --git a/components/js_injection/common/interfaces.mojom b/components/js_injection/common/interfaces.mojom
index 3618729..c2e43d2 100644
--- a/components/js_injection/common/interfaces.mojom
+++ b/components/js_injection/common/interfaces.mojom
@@ -28,12 +28,19 @@
   js_injection.mojom.OriginMatcher origin_matcher;
 };
 
+// JsWebMessage struct contains the message payload sent between
+// JavaScript and Browser.
+// TODO(crbug.com/1374142): Add ArrayBuffer support.
+union JsWebMessage {
+  mojo_base.mojom.String16 string_value;
+};
+
 // For JavaScript postMessage() API, implemented by browser.
 interface JsToBrowserMessaging {
   // Called from renderer, browser receives |message| and possible |ports|,
   // The |message| is an opaque type and the contents are defined by the client
   // of this API.
-  PostMessage(mojo_base.mojom.String16 message,
+  PostMessage(JsWebMessage message,
               array<blink.mojom.MessagePortDescriptor> ports);
 
   // When there is a new BrowserToJsMessaging created in renderer, we need to
@@ -46,7 +53,7 @@
 // the renderer.
 interface BrowserToJsMessaging {
   // Called from browser, to send message to page.
-  OnPostMessage(mojo_base.mojom.String16 message);
+  OnPostMessage(JsWebMessage message);
 };
 
 // For browser to configure renderer, implemented by renderer.
diff --git a/components/js_injection/common/web_message.cc b/components/js_injection/common/web_message.cc
new file mode 100644
index 0000000..69ed1841
--- /dev/null
+++ b/components/js_injection/common/web_message.cc
@@ -0,0 +1,17 @@
+// 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.
+
+#include "components/js_injection/common/web_message.h"
+
+#include <string>
+
+namespace js_injection {
+
+JsWebMessage::JsWebMessage() = default;
+
+JsWebMessage::JsWebMessage(JsWebMessage&&) = default;
+
+JsWebMessage& JsWebMessage::operator=(JsWebMessage&&) = default;
+
+}  // namespace js_injection
diff --git a/components/js_injection/common/web_message.h b/components/js_injection/common/web_message.h
new file mode 100644
index 0000000..c8a79be9
--- /dev/null
+++ b/components/js_injection/common/web_message.h
@@ -0,0 +1,24 @@
+// 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.
+
+#ifndef COMPONENTS_JS_INJECTION_COMMON_WEB_MESSAGE_H_
+#define COMPONENTS_JS_INJECTION_COMMON_WEB_MESSAGE_H_
+
+#include <string>
+
+namespace js_injection {
+
+// A struct representing mojo type `js_injection.mojom.JsWebMessage`.
+struct JsWebMessage {
+  JsWebMessage();
+  JsWebMessage(JsWebMessage&) = delete;
+  JsWebMessage(JsWebMessage&&);
+  JsWebMessage& operator=(JsWebMessage&) = delete;
+  JsWebMessage& operator=(JsWebMessage&&);
+
+  std::u16string string;
+};
+}  // namespace js_injection
+
+#endif
diff --git a/components/js_injection/common/web_message_mojom_traits.cc b/components/js_injection/common/web_message_mojom_traits.cc
new file mode 100644
index 0000000..088f63d
--- /dev/null
+++ b/components/js_injection/common/web_message_mojom_traits.cc
@@ -0,0 +1,28 @@
+// 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.
+
+#include "components/js_injection/common/web_message_mojom_traits.h"
+
+#include <string>
+#include "components/js_injection/common/interfaces.mojom.h"
+#include "components/js_injection/common/web_message.h"
+#include "mojo/public/cpp/bindings/union_traits.h"
+
+namespace mojo {
+
+// static
+bool UnionTraits<js_injection::mojom::JsWebMessageDataView,
+                 js_injection::JsWebMessage>::
+    Read(js_injection::mojom::JsWebMessageDataView r,
+         js_injection::JsWebMessage* out) {
+  std::u16string string_value;
+  if (!r.ReadStringValue(&string_value))
+    return false;
+
+  out->string = std::move(string_value);
+
+  return true;
+}
+
+}  // namespace mojo
diff --git a/components/js_injection/common/web_message_mojom_traits.h b/components/js_injection/common/web_message_mojom_traits.h
new file mode 100644
index 0000000..ae89e20
--- /dev/null
+++ b/components/js_injection/common/web_message_mojom_traits.h
@@ -0,0 +1,34 @@
+// 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.
+
+#ifndef COMPONENTS_JS_INJECTION_COMMON_WEB_MESSAGE_MOJOM_TRAITS_H_
+#define COMPONENTS_JS_INJECTION_COMMON_WEB_MESSAGE_MOJOM_TRAITS_H_
+
+#include <string>
+#include "components/js_injection/common/interfaces.mojom-shared.h"
+#include "components/js_injection/common/web_message.h"
+#include "mojo/public/cpp/bindings/union_traits.h"
+
+namespace mojo {
+
+template <>
+struct UnionTraits<js_injection::mojom::JsWebMessageDataView,
+                   js_injection::JsWebMessage> {
+  static std::u16string string_value(
+      const js_injection::JsWebMessage& message) {
+    return message.string;
+  }
+
+  static js_injection::mojom::JsWebMessageDataView::Tag GetTag(
+      const js_injection::JsWebMessage& input) {
+    return js_injection::mojom::JsWebMessageDataView::Tag::kStringValue;
+  }
+
+  static bool Read(js_injection::mojom::JsWebMessageDataView r,
+                   js_injection::JsWebMessage* out);
+};
+
+}  // namespace mojo
+
+#endif
diff --git a/components/js_injection/renderer/js_binding.cc b/components/js_injection/renderer/js_binding.cc
index 395b5cf..4c27faf 100644
--- a/components/js_injection/renderer/js_binding.cc
+++ b/components/js_injection/renderer/js_binding.cc
@@ -9,6 +9,7 @@
 #include "base/containers/contains.h"
 #include "base/ranges/algorithm.h"
 #include "base/strings/string_util.h"
+#include "components/js_injection/common/web_message.h"
 #include "components/js_injection/renderer/js_communication.h"
 #include "content/public/renderer/render_frame.h"
 #include "gin/data_object_builder.h"
@@ -86,7 +87,7 @@
 
 JsBinding::~JsBinding() = default;
 
-void JsBinding::OnPostMessage(const std::u16string& message) {
+void JsBinding::OnPostMessage(JsWebMessage message) {
   // If `js_communication_` is null, this object will soon be destroyed.
   if (!js_communication_)
     return;
@@ -111,7 +112,7 @@
   // Simulate MessageEvent's data property. See
   // https://html.spec.whatwg.org/multipage/comms.html#messageevent
   v8::Local<v8::Object> event =
-      gin::DataObjectBuilder(isolate).Set("data", message).Build();
+      gin::DataObjectBuilder(isolate).Set("data", message.string).Build();
   v8::Local<v8::Value> argv[] = {event};
 
   v8::Local<v8::Object> self = GetWrapper(isolate).ToLocalChecked();
@@ -182,8 +183,11 @@
       js_communication_ ? js_communication_->GetJsToJavaMessage(js_object_name_)
                         : nullptr;
   if (js_to_java_messaging) {
+    JsWebMessage js_message;
+    js_message.string = std::move(message);
     js_to_java_messaging->PostMessage(
-        message, blink::MessagePortChannel::ReleaseHandles(ports));
+        std::move(js_message),
+        blink::MessagePortChannel::ReleaseHandles(ports));
   }
 }
 
diff --git a/components/js_injection/renderer/js_binding.h b/components/js_injection/renderer/js_binding.h
index 12ce8a7..aeeba2a 100644
--- a/components/js_injection/renderer/js_binding.h
+++ b/components/js_injection/renderer/js_binding.h
@@ -27,6 +27,7 @@
 
 namespace js_injection {
 class JsCommunication;
+struct JsWebMessage;
 
 // A gin::Wrappable class used for providing JavaScript API. JsCommunication
 // creates an instance of JsBinding for each unique name exposed to the page.
@@ -45,7 +46,7 @@
       base::WeakPtr<JsCommunication> js_communication);
 
   // mojom::BrowserToJsMessaging implementation.
-  void OnPostMessage(const std::u16string& message) override;
+  void OnPostMessage(JsWebMessage message) override;
 
   void ReleaseV8GlobalObjects();
 
diff --git a/components/password_manager/content/browser/content_password_manager_driver.cc b/components/password_manager/content/browser/content_password_manager_driver.cc
index 8ceea64eb..af27ec0 100644
--- a/components/password_manager/content/browser/content_password_manager_driver.cc
+++ b/components/password_manager/content/browser/content_password_manager_driver.cc
@@ -484,15 +484,13 @@
 
 const mojo::AssociatedRemote<autofill::mojom::PasswordAutofillAgent>&
 ContentPasswordManagerDriver::GetPasswordAutofillAgent() {
-  if (render_frame_host_->IsAnonymous()) {
+  if (render_frame_host_->IsAnonymous() ||
+      render_frame_host_->GetLifecycleState() ==
+          content::RenderFrameHost::LifecycleState::kPrerendering) {
     password_autofill_agent_.reset();
     return password_autofill_agent_;  // Unbound remote.
   }
 
-  DCHECK(!password_autofill_agent_ ||
-         (content::RenderFrameHost::LifecycleState::kPrerendering !=
-          render_frame_host_->GetLifecycleState()));
-
   if (!password_autofill_agent_) {
     // Some test environments may have no remote interface support.
     if (render_frame_host_->GetRemoteAssociatedInterfaces()) {
diff --git a/components/password_manager/core/browser/sync/password_sync_bridge.cc b/components/password_manager/core/browser/sync/password_sync_bridge.cc
index 27944d1..335f05c 100644
--- a/components/password_manager/core/browser/sync/password_sync_bridge.cc
+++ b/components/password_manager/core/browser/sync/password_sync_bridge.cc
@@ -185,11 +185,8 @@
 // merge.
 bool ShouldRecoverPasswordsDuringMerge() {
   // Delete the local undecryptable copy when this is MacOS only.
-#if BUILDFLAG(IS_MAC)
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
   return true;
-#elif BUILDFLAG(IS_LINUX)
-  return base::FeatureList::IsEnabled(
-      features::kSyncUndecryptablePasswordsLinux);
 #else
   return false;
 #endif
diff --git a/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc b/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc
index 89528573f..91554e9 100644
--- a/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc
+++ b/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc
@@ -896,7 +896,6 @@
   feature_list.InitWithFeatures(
       {
           features::kForceInitialSyncWhenDecryptionFails,
-          features::kSyncUndecryptablePasswordsLinux,
       },
       {});
   ON_CALL(*mock_password_store_sync(), ReadAllCredentials)
@@ -1147,7 +1146,6 @@
   feature_list.InitWithFeatures(
       {
           features::kForceInitialSyncWhenDecryptionFails,
-          features::kSyncUndecryptablePasswordsLinux,
       },
       {});
 
@@ -1278,11 +1276,6 @@
       public testing::WithParamInterface<FormRetrievalResult> {
  protected:
   void ShouldDeleteUndecryptableLoginsDuringMerge() {
-#if BUILDFLAG(IS_LINUX)
-    base::test::ScopedFeatureList feature_list;
-    feature_list.InitAndEnableFeature(
-        features::kSyncUndecryptablePasswordsLinux);
-#endif
     ON_CALL(*mock_password_store_sync(), DeleteUndecryptableCredentials())
         .WillByDefault(Return(DatabaseCleanupResult::kSuccess));
 
diff --git a/components/password_manager/core/common/password_manager_features.cc b/components/password_manager/core/common/password_manager_features.cc
index f681d5c..9b3839c 100644
--- a/components/password_manager/core/common/password_manager_features.cc
+++ b/components/password_manager/core/common/password_manager_features.cc
@@ -230,14 +230,6 @@
              base::FEATURE_DISABLED_BY_DEFAULT);
 #endif
 
-#if BUILDFLAG(IS_LINUX)
-// When enabled, all undecryptable passwords are deleted from the local database
-// during initial sync flow.
-BASE_FEATURE(kSyncUndecryptablePasswordsLinux,
-             "SyncUndecryptablePasswordsLinux",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-#endif
-
 #if BUILDFLAG(IS_ANDROID)
 BASE_FEATURE(kPasswordEditDialogWithDetails,
              "PasswordEditDialogWithDetails",
diff --git a/components/password_manager/core/common/password_manager_features.h b/components/password_manager/core/common/password_manager_features.h
index d9cf629..f08c83d 100644
--- a/components/password_manager/core/common/password_manager_features.h
+++ b/components/password_manager/core/common/password_manager_features.h
@@ -68,9 +68,6 @@
 #if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
 BASE_DECLARE_FEATURE(kSkipUndecryptablePasswords);
 #endif
-#if BUILDFLAG(IS_LINUX)
-BASE_DECLARE_FEATURE(kSyncUndecryptablePasswordsLinux);
-#endif
 #if BUILDFLAG(IS_ANDROID)
 BASE_DECLARE_FEATURE(kPasswordEditDialogWithDetails);
 BASE_DECLARE_FEATURE(kShowUPMErrorNotification);
diff --git a/components/policy/core/browser/policy_pref_mapping_test.cc b/components/policy/core/browser/policy_pref_mapping_test.cc
index 1314a3ad..9108327 100644
--- a/components/policy/core/browser/policy_pref_mapping_test.cc
+++ b/components/policy/core/browser/policy_pref_mapping_test.cc
@@ -672,6 +672,10 @@
           }
           ASSERT_TRUE(expected_value);
 
+          // TODO(crbug/1372598) remove logs once root cause has been found
+          LOG(INFO) << "Test case name: " << test_case->name()
+                    << "\t index: " << i << "\t pref: " << pref_case->pref();
+
           if (check_recommended) {
             SCOPED_TRACE(::testing::Message() << "checking recommended policy");
 
@@ -700,6 +704,9 @@
       }
     }
   }
+
+  // TODO(crbug/1372598) remove logs once root cause has been found
+  LOG(INFO) << "All tests done";
 }
 
 }  // namespace policy
diff --git a/components/reporting/proto/synced/health.proto b/components/reporting/proto/synced/health.proto
index 6f5f405..dc74c33 100644
--- a/components/reporting/proto/synced/health.proto
+++ b/components/reporting/proto/synced/health.proto
@@ -13,13 +13,13 @@
 
 // Information about records being removed from a storage queue.
 message StorageDequeue {
-  optional int64 sequencing_id = 1;
-  optional int64 records_count = 2;
+  optional int64 sequencing_id = 1;  // required
+  optional int64 records_count = 2;  // required
 }
 
 // Information about records being added to a storage queue.
 message StorageEnqueue {
-  optional int64 sequencing_id = 1;
+  optional int64 sequencing_id = 1;  // required
 }
 
 // Data about a record being added or removed from a storage queue
@@ -28,33 +28,56 @@
     StorageDequeue storage_dequeue = 1;
     StorageEnqueue storage_enqueue = 2;
   }
-
-  optional StatusProto status = 3;
+  optional Priority priority = 3;   // required
+  optional StatusProto status = 4;  // OK if absent.
 }
 
 // Data about the EnqueueRecord dBus call.
 message EnqueueRecordCall {
-  optional Priority priority = 1;
-  optional StatusProto status = 2;
+  optional Priority priority = 1;        // required
+  optional Destination destination = 2;  // required
+  optional StatusProto status = 3;       // OK if absent.
 }
 
 // Data about the FlushPriority dBus call.
 message FlushPriorityCall {
-  optional Priority priority = 1;
-  optional StatusProto status = 2;
+  optional Priority priority = 1;   // required
+  optional StatusProto status = 2;  // OK if absent.
+}
+
+// Single upload record item.
+message UploadRecordItem {
+  optional int64 sequencing_id = 1;  // required
+}
+
+// Single upload gap item.
+message UploadGapItem {
+  optional int64 sequencing_id = 1;  // required
+  optional int64 count = 2;          // required
+}
+
+// Single upload item.
+message UploadItem {
+  oneof item {
+    UploadRecordItem record = 1;
+    UploadGapItem gap = 2;
+  }
 }
 
 // Data about the UploadEncryptedRecord dBus call.
 message UploadEncryptedRecordCall {
-  optional int64 sequencing_id = 1;
-  optional bool encryption_key_requested = 2;
-  optional StatusProto status = 3;
+  repeated UploadItem items = 1;
+  optional string upload_reason = 2;  // required
+  optional Priority priority = 3;     // required
+  optional StatusProto status = 4;    // OK if absent.
 }
 
 // Data about the ConfirmRecordUpload dBus call.
 message ConfirmRecordUploadCall {
-  optional int64 sequencing_id = 1;
+  optional int64 sequencing_id = 1;  // required
   optional bool force_confirm = 2;
+  optional Priority priority = 3;   // required
+  optional StatusProto status = 4;  // OK if absent.
 }
 
 message HealthDataHistory {
@@ -66,10 +89,10 @@
     StorageQueueAction storage_queue_action = 5;
   }
 
-  optional int64 timestamp_seconds = 6;
+  optional int64 timestamp_seconds = 6;  // required
 }
 
 // Aggregate health data of the ERP.
 message ERPHealthData {
-  repeated HealthDataHistory history = 1;
+  repeated HealthDataHistory history = 1;  // required
 }
diff --git a/components/reporting/storage/storage_queue.cc b/components/reporting/storage/storage_queue.cc
index 8ea89d1..a99e74e 100644
--- a/components/reporting/storage/storage_queue.cc
+++ b/components/reporting/storage/storage_queue.cc
@@ -980,7 +980,7 @@
     }
   }
 
-  void OnCompletion() override {
+  void OnCompletion(const Status& status) override {
     DCHECK_CALLED_ON_VALID_SEQUENCE(
         storage_queue_->storage_queue_sequence_checker_);
     // Unregister with storage_queue.
diff --git a/components/reporting/util/task_runner_context.h b/components/reporting/util/task_runner_context.h
index cca37809..d8839148 100644
--- a/components/reporting/util/task_runner_context.h
+++ b/components/reporting/util/task_runner_context.h
@@ -95,7 +95,7 @@
   // (can only be called by action scheduled to the sequenced task runner).
   void Response(ResponseType result) {
     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    OnCompletion();
+    OnCompletion(result);
 
     // Respond to the caller.
     DCHECK(!callback_.is_null()) << "Already responded";
@@ -138,7 +138,7 @@
 
   // Finalization action before responding and deleting the context.
   // May be overridden, if necessary.
-  virtual void OnCompletion() {}
+  virtual void OnCompletion(const ResponseType& result) {}
 
   // Wrapper for OnStart to mandate sequence checker.
   void OnStartWrap() {
diff --git a/components/safe_browsing/content/browser/browser_url_loader_throttle.cc b/components/safe_browsing/content/browser/browser_url_loader_throttle.cc
index 1aa1de3e..1785ed4 100644
--- a/components/safe_browsing/content/browser/browser_url_loader_throttle.cc
+++ b/components/safe_browsing/content/browser/browser_url_loader_throttle.cc
@@ -227,6 +227,8 @@
 
   original_url_ = request->url;
   pending_checks_++;
+  start_request_time_ = base::TimeTicks::Now();
+  is_start_request_called_ = true;
   content::GetIOThreadTaskRunner({})->PostTask(
       FROM_HERE, base::BindOnce(&BrowserURLLoaderThrottle::CheckerOnIO::Start,
                                 io_checker_->AsWeakPtr(), request->headers,
@@ -280,6 +282,12 @@
   base::UmaHistogramBoolean(
       "SafeBrowsing.BrowserThrottle.IsCheckCompletedOnProcessResponse",
       check_completed);
+  if (is_start_request_called_) {
+    base::UmaHistogramTimes(
+        "SafeBrowsing.BrowserThrottle.IntervalBetweenStartAndProcess",
+        base::TimeTicks::Now() - start_request_time_);
+    is_start_request_called_ = false;
+  }
 
   if (check_completed)
     return;
diff --git a/components/safe_browsing/content/browser/browser_url_loader_throttle.h b/components/safe_browsing/content/browser/browser_url_loader_throttle.h
index da405327..1f261023 100644
--- a/components/safe_browsing/content/browser/browser_url_loader_throttle.h
+++ b/components/safe_browsing/content/browser/browser_url_loader_throttle.h
@@ -110,6 +110,10 @@
   size_t pending_slow_checks_ = 0;
   bool blocked_ = false;
 
+  // The time when |WillStartRequest| is called.
+  base::TimeTicks start_request_time_;
+  bool is_start_request_called_ = false;
+
   // The time when we started deferring the request.
   base::TimeTicks defer_start_time_;
   bool deferred_ = false;
diff --git a/components/safe_browsing/content/renderer/renderer_url_loader_throttle.cc b/components/safe_browsing/content/renderer/renderer_url_loader_throttle.cc
index 23be14b..3a09120 100644
--- a/components/safe_browsing/content/renderer/renderer_url_loader_throttle.cc
+++ b/components/safe_browsing/content/renderer/renderer_url_loader_throttle.cc
@@ -66,6 +66,8 @@
 
   original_url_ = request->url;
   pending_checks_++;
+  start_request_time_ = base::TimeTicks::Now();
+  is_start_request_called_ = true;
   // Use a weak pointer to self because |safe_browsing_| may not be owned by
   // this object.
   net::HttpRequestHeaders headers;
@@ -117,6 +119,12 @@
   base::UmaHistogramBoolean(
       "SafeBrowsing.RendererThrottle.IsCheckCompletedOnProcessResponse",
       check_completed);
+  if (is_start_request_called_) {
+    base::UmaHistogramTimes(
+        "SafeBrowsing.RendererThrottle.IntervalBetweenStartAndProcess",
+        base::TimeTicks::Now() - start_request_time_);
+    is_start_request_called_ = false;
+  }
 
   if (check_completed)
     return;
diff --git a/components/safe_browsing/content/renderer/renderer_url_loader_throttle.h b/components/safe_browsing/content/renderer/renderer_url_loader_throttle.h
index 96921d83..cd27af7 100644
--- a/components/safe_browsing/content/renderer/renderer_url_loader_throttle.h
+++ b/components/safe_browsing/content/renderer/renderer_url_loader_throttle.h
@@ -86,6 +86,10 @@
   size_t pending_slow_checks_ = 0;
   bool blocked_ = false;
 
+  // The time when |WillStartRequest| is called.
+  base::TimeTicks start_request_time_;
+  bool is_start_request_called_ = false;
+
   // The time when we started deferring the request.
   base::TimeTicks defer_start_time_;
   bool deferred_ = false;
diff --git a/components/sync/driver/sync_auth_manager.cc b/components/sync/driver/sync_auth_manager.cc
index 95bf634..9ecf7dd 100644
--- a/components/sync/driver/sync_auth_manager.cc
+++ b/components/sync/driver/sync_auth_manager.cc
@@ -414,6 +414,12 @@
   credentials_changed_callback_.Run();
 }
 
+void SyncAuthManager::OnErrorStateOfRefreshTokenUpdatedForAccount(
+    const CoreAccountInfo& account_info,
+    const GoogleServiceAuthError& error) {
+  OnRefreshTokenUpdatedForAccount(account_info);
+}
+
 void SyncAuthManager::OnRefreshTokensLoaded() {
   DCHECK(IsActiveAccountInfoFullyLoaded());
 
diff --git a/components/sync/driver/sync_auth_manager.h b/components/sync/driver/sync_auth_manager.h
index fa8247a..033abd3 100644
--- a/components/sync/driver/sync_auth_manager.h
+++ b/components/sync/driver/sync_auth_manager.h
@@ -112,6 +112,9 @@
       const CoreAccountInfo& account_info) override;
   void OnRefreshTokenRemovedForAccount(
       const CoreAccountId& account_id) override;
+  void OnErrorStateOfRefreshTokenUpdatedForAccount(
+      const CoreAccountInfo& account_info,
+      const GoogleServiceAuthError& error) override;
   void OnRefreshTokensLoaded() override;
 
   // Test-only methods for inspecting/modifying internal state.
diff --git a/components/sync/driver/sync_auth_manager_unittest.cc b/components/sync/driver/sync_auth_manager_unittest.cc
index ef816c3..3909286 100644
--- a/components/sync/driver/sync_auth_manager_unittest.cc
+++ b/components/sync/driver/sync_auth_manager_unittest.cc
@@ -7,11 +7,13 @@
 #include "base/callback_helpers.h"
 #include "base/run_loop.h"
 #include "base/test/mock_callback.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "components/signin/public/identity_manager/identity_test_environment.h"
 #include "components/signin/public/identity_manager/primary_account_mutator.h"
+#include "components/sync/base/features.h"
 #include "components/sync/engine/connection_status.h"
 #include "components/sync/engine/sync_credentials.h"
 #include "net/base/net_errors.h"
@@ -722,6 +724,41 @@
   base::RunLoop().RunUntilIdle();
 }
 
+TEST_F(SyncAuthManagerTest, EntersPausedStateOnPersistentAuthError) {
+  base::test::ScopedFeatureList feature(kSyncPauseUponAnyPersistentAuthError);
+
+  CoreAccountId account_id =
+      identity_env()
+          ->MakePrimaryAccountAvailable("test@email.com",
+                                        signin::ConsentLevel::kSync)
+          .account_id;
+  std::unique_ptr<SyncAuthManager> auth_manager = CreateAuthManager();
+  auth_manager->RegisterForAuthNotifications();
+  ASSERT_EQ(auth_manager->GetActiveAccountInfo().account_info.account_id,
+            account_id);
+
+  auth_manager->ConnectionOpened();
+  identity_env()->WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
+      "access_token", base::Time::Now() + base::Hours(1));
+  ASSERT_EQ(auth_manager->GetCredentials().access_token, "access_token");
+
+  // Now everything is okay for a while.
+  auth_manager->ConnectionStatusChanged(syncer::CONNECTION_OK);
+  ASSERT_EQ(auth_manager->GetCredentials().access_token, "access_token");
+  ASSERT_EQ(auth_manager->GetLastAuthError(),
+            GoogleServiceAuthError::AuthErrorNone());
+
+  // But now an auth error happens.
+  identity_env()->UpdatePersistentErrorOfRefreshTokenForAccount(
+      auth_manager->GetActiveAccountInfo().account_info.account_id,
+      GoogleServiceAuthError::FromServiceError("Test error"));
+
+  // Should immediately drop the access token and enter the sync-paused state.
+  EXPECT_TRUE(auth_manager->GetCredentials().access_token.empty());
+  EXPECT_TRUE(auth_manager->GetLastAuthError().IsPersistentError());
+  EXPECT_TRUE(auth_manager->IsSyncPaused());
+}
+
 TEST_F(SyncAuthManagerTest,
        RequestsAccessTokenWhenInvalidRefreshTokenResolved) {
   CoreAccountId account_id =
@@ -780,7 +817,10 @@
   // An invalid refresh token gets set, i.e. we enter the "Sync paused" state
   // (only from SyncAuthManager's point of view - Sync as a whole is still
   // disabled).
-  EXPECT_CALL(credentials_changed, Run());
+  // Note: Depending on the exact sequence of IdentityManager::Observer calls
+  // (refresh token changed and/or auth error changed), the credentials-changed
+  // callback might get run multiple times.
+  EXPECT_CALL(credentials_changed, Run()).Times(testing::AtLeast(1));
   identity_env()->SetInvalidRefreshTokenForPrimaryAccount();
   ASSERT_TRUE(auth_manager->GetCredentials().access_token.empty());
   ASSERT_TRUE(auth_manager->IsSyncPaused());
diff --git a/components/sync/driver/sync_service_impl_startup_unittest.cc b/components/sync/driver/sync_service_impl_startup_unittest.cc
index 92ffffe..089ef02d 100644
--- a/components/sync/driver/sync_service_impl_startup_unittest.cc
+++ b/components/sync/driver/sync_service_impl_startup_unittest.cc
@@ -273,10 +273,15 @@
   sync_service()->AddObserver(&observer);
 
   // Entering the sync-paused state should trigger a notification.
-  EXPECT_CALL(observer, OnStateChanged(sync_service())).WillOnce([&]() {
-    EXPECT_EQ(SyncService::TransportState::PAUSED,
-              sync_service()->GetTransportState());
-  });
+  // Note: Depending on the exact sequence of IdentityManager::Observer calls
+  // (refresh token changed and/or auth error changed), there might be multiple
+  // notifications.
+  EXPECT_CALL(observer, OnStateChanged(sync_service()))
+      .Times(testing::AtLeast(1))
+      .WillRepeatedly([&]() {
+        EXPECT_EQ(SyncService::TransportState::PAUSED,
+                  sync_service()->GetTransportState());
+      });
 
   // Now sign out on the web to enter the sync-paused state.
   SimulateWebSignout();
@@ -309,10 +314,15 @@
   sync_service()->AddObserver(&observer);
 
   // Entering the sync-paused state should trigger a notification.
-  EXPECT_CALL(observer, OnStateChanged(sync_service())).WillOnce([&]() {
-    EXPECT_EQ(SyncService::TransportState::PAUSED,
-              sync_service()->GetTransportState());
-  });
+  // Note: Depending on the exact sequence of IdentityManager::Observer calls
+  // (refresh token changed and/or auth error changed), there might be multiple
+  // notifications.
+  EXPECT_CALL(observer, OnStateChanged(sync_service()))
+      .Times(testing::AtLeast(1))
+      .WillRepeatedly([&]() {
+        EXPECT_EQ(SyncService::TransportState::PAUSED,
+                  sync_service()->GetTransportState());
+      });
 
   // Now sign out on the web to enter the sync-paused state.
   SimulateWebSignout();
diff --git a/components/variations/BUILD.gn b/components/variations/BUILD.gn
index 46b6d3ba..a60d84d4 100644
--- a/components/variations/BUILD.gn
+++ b/components/variations/BUILD.gn
@@ -216,6 +216,7 @@
     "simulate_for_crosstalk_unittest.cc",
     "study_filtering_unittest.cc",
     "synthetic_trial_registry_unittest.cc",
+    "uniformity_unittest.cc",
     "variations_associated_data_unittest.cc",
     "variations_ids_provider_unittest.cc",
     "variations_murmur_hash_unittest.cc",
diff --git a/components/variations/processed_study.cc b/components/variations/processed_study.cc
index f19fdd8..ef874066 100644
--- a/components/variations/processed_study.cc
+++ b/components/variations/processed_study.cc
@@ -190,10 +190,15 @@
       all_assignments_to_one_group_) {
     return base::FieldTrialList::GetEntropyProviderForSessionRandomization();
   }
-  if (ShouldStudyUseLowEntropy()) {
-    return entropy_providers.low_entropy();
+  if (entropy_providers.default_entropy_is_high_entropy() &&
+      !ShouldStudyUseLowEntropy()) {
+    // We can use the high entropy source to randomize this study, which will
+    // be uniform even if the study is conditioned on layer membership.
+    return entropy_providers.default_entropy();
   }
-  return entropy_providers.default_entropy();
+  if (study_->has_layer())
+    return layers.GetRemainderEntropy(study_->layer().layer_id());
+  return entropy_providers.low_entropy();
 }
 
 int ProcessedStudy::GetExperimentIndexByName(const std::string& name) const {
diff --git a/components/variations/uniformity_unittest.cc b/components/variations/uniformity_unittest.cc
new file mode 100644
index 0000000..67b2fc9c
--- /dev/null
+++ b/components/variations/uniformity_unittest.cc
@@ -0,0 +1,250 @@
+// 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.
+
+#include <stdint.h>
+
+#include <initializer_list>
+#include <memory>
+
+#include "base/feature_list.h"
+#include "base/functional/bind.h"
+#include "base/strings/stringprintf.h"
+#include "base/test/scoped_feature_list.h"
+#include "components/variations/entropy_provider.h"
+#include "components/variations/proto/study.pb.h"
+#include "components/variations/proto/variations_seed.pb.h"
+#include "components/variations/variations_seed_processor.h"
+#include "components/variations/variations_test_utils.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace variations {
+namespace {
+
+// For these tests, we use a small LES range to make the expectations simpler.
+const uint32_t kMaxEntropy = 20;
+const char kStudyName[] = "Uniformity";
+
+struct LayerStudySeedOptions {
+  bool layer_constrain_study = true;
+  bool force_low_entropy_layer = true;
+  bool force_low_entropy = false;
+  uint32_t slot_multiplier = 1;
+};
+
+// Generates a seed for checking uniformity of assignments in layered
+// constrained study. This seed contains a 3 arm study active in 9/10 slots.
+// |slot_multiplier| increased the number of slots in each range, but should not
+// affect randomization.
+VariationsSeed LayerStudySeed(LayerStudySeedOptions options) {
+  VariationsSeed seed;
+  Layer* layer = seed.add_layers();
+  layer->set_id(42);
+  layer->set_num_slots(10 * options.slot_multiplier);
+  if (options.force_low_entropy_layer)
+    layer->set_entropy_mode(Layer::LOW);
+  Layer::LayerMember* member = layer->add_members();
+  member->set_id(82);
+  // Use a 9/10 slots, but with the slots into a 4 and 5 slot chunk that are
+  // discontiguous. Neither range alone will allow uniform randomization if
+  // 3 does not divide the range of the LES values.
+  Layer::LayerMember::SlotRange* slot = member->add_slots();
+  slot->set_start(0 * options.slot_multiplier);
+  slot->set_end(4 * options.slot_multiplier);
+  slot = member->add_slots();
+  slot->set_start(6 * options.slot_multiplier);
+  slot->set_end(9 * options.slot_multiplier);
+
+  Study* study = seed.add_study();
+  study->set_name(kStudyName);
+  study->set_consistency(Study_Consistency_PERMANENT);
+
+  if (options.layer_constrain_study) {
+    LayerMemberReference* layer_membership = study->mutable_layer();
+    layer_membership->set_layer_id(42);
+    layer_membership->set_layer_member_id(82);
+  }
+  // Use 3 arms, which does not divide
+  for (auto* group_name : {"A", "B", "C"}) {
+    auto* exp = study->add_experiment();
+    exp->set_name(group_name);
+    exp->set_probability_weight(1);
+  }
+  if (options.force_low_entropy) {
+    study->mutable_experiment(0)->set_google_web_experiment_id(12345);
+  }
+  return seed;
+}
+
+// When assigned directly from low entropy, the following assignments are used
+// for the study.
+const std::vector<std::string> kExpectedLowEntropyAssignments = {
+    "C", "A", "B", "C", "A", "B", "C", "A", "B", "B",  // 10
+    "B", "A", "C", "C", "C", "A", "B", "B", "A", "A",  // 20
+};
+
+// LayeredStudySeed should give the following assignment using the test LES.
+// All 3 arms get 6/20 values, with 2/20 not in the study.
+const std::vector<std::string> kExpectedRemainderEntropyAssignments = {
+    "A", "A", "C", "A", "C", "B", "A", "A", "A", "C",  // 10
+    "B", "B", "C", "",  "C", "B", "C", "B", "",  "B",  // 20
+};
+
+// The expected group assignments for the study based on high entropy.
+// This does not take into account any layer exclusions.
+// This is only a small sample of the entropy space, so we don't expect
+// precised uniformity, just a reasonable mixture.
+const std::vector<std::string> kExpectedHighEntropyStudyAssignments = {
+    "C", "B", "A", "B", "A", "B", "A", "A", "B", "C",  // 10
+    "B", "A", "A", "C", "C", "A", "A", "B", "B", "C",  // 20
+    "C", "A", "C", "A", "C", "A", "B", "B", "A", "B",  // 30
+    "A", "B", "C", "B", "B", "C", "C", "C", "B", "B",  // 40
+    "C", "B", "B", "C", "C", "B", "A", "B", "C", "C",  // 50
+    "C", "B", "C", "C", "B", "B", "C", "B", "A", "A",  // 60
+    "B", "C", "A", "C", "A", "B", "B", "C", "B", "A",  // 70
+    "B", "B", "A", "B", "A", "C", "B", "A", "B", "B",  // 80
+    "B", "A", "B", "C", "C", "B", "A", "A", "C", "A",  // 90
+    "A", "A", "C", "B", "B", "C", "B", "C", "A", "C",  // 100
+};
+
+// Process the seed and return which group the user is assigned for Uniformity.
+std::string GetUniformityAssignment(const VariationsSeed& seed,
+                                    const EntropyProviders& entropy_providers) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.Init();
+  base::FeatureList feature_list;
+  auto client_state = CreateDummyClientFilterableState();
+  // This should mimic the call through SetUpFieldTrials from
+  // android_webview/browser/aw_feature_list_creator.cc
+  VariationsSeedProcessor().CreateTrialsFromSeed(
+      seed, *client_state, base::BindRepeating(NoopUIStringOverrideCallback),
+      entropy_providers, &feature_list);
+  testing::ClearAllVariationIDs();
+  return base::FieldTrialList::FindFullName(kStudyName);
+}
+
+// Process the seed and return which group the user is assigned for Uniformity.
+std::vector<std::string> GetUniformityAssignments(const VariationsSeed& seed) {
+  std::vector<std::string> result;
+  // Add 20 clients that do not have client IDs, 1 per low entropy value.
+  for (uint32_t i = 0; i < kMaxEntropy; i++) {
+    result.push_back(
+        GetUniformityAssignment(seed, EntropyProviders("", i, kMaxEntropy)));
+  }
+  // Add 100 clients that do have client IDs, 5 per low entropy value.
+  for (uint32_t i = 0; i < kMaxEntropy * 5; i++) {
+    result.push_back(GetUniformityAssignment(
+        seed, EntropyProviders(base::StringPrintf("clientid_%02d", i),
+                               i % kMaxEntropy, kMaxEntropy)));
+  }
+  return result;
+}
+
+std::vector<std::string> Concat(
+    std::initializer_list<const std::vector<std::string>*> vectors) {
+  std::vector<std::string> result;
+  for (auto* const vector : vectors) {
+    result.insert(result.end(), vector->begin(), vector->end());
+  }
+  return result;
+}
+
+}  // namespace
+
+// We should get the same assignments for clients that have no high entropy.
+// This should be true for both types of layer entropy.
+TEST(VariationsUniformityTest, UnlayeredDefaultEntropyStudy) {
+  auto assignments = GetUniformityAssignments(
+      LayerStudySeed({.layer_constrain_study = false}));
+
+  std::vector<std::string> expected = Concat({
+      // Low entropy clients assign based on low entropy.
+      &kExpectedLowEntropyAssignments,
+      // High entropy clients assign based on high entropy.
+      // No exclusions by layer.
+      &kExpectedHighEntropyStudyAssignments,
+  });
+  EXPECT_THAT(assignments, ::testing::ElementsAreArray(expected));
+}
+
+// We should get the same assignments for clients that have no high entropy.
+// This should be true for both types of layer entropy.
+TEST(VariationsUniformityTest, UnlayeredLowEntropyStudy) {
+  auto assignments = GetUniformityAssignments(LayerStudySeed(
+      {.layer_constrain_study = false, .force_low_entropy = true}));
+
+  std::vector<std::string> expected = Concat({
+      // Low entropy clients assign based on low entropy.
+      &kExpectedLowEntropyAssignments,
+      // High entropy clients assign based on low entropy.
+      // No exclusions by layer.
+      &kExpectedLowEntropyAssignments,
+      &kExpectedLowEntropyAssignments,
+      &kExpectedLowEntropyAssignments,
+      &kExpectedLowEntropyAssignments,
+      &kExpectedLowEntropyAssignments,
+  });
+  EXPECT_THAT(assignments, ::testing::ElementsAreArray(expected));
+}
+
+TEST(VariationsUniformityTest, LowEntropyLayerDefaultEntropyStudy) {
+  auto assignments = GetUniformityAssignments(LayerStudySeed({}));
+
+  std::vector<std::string> expected = Concat({
+      // Low entropy clients assign based on remainder entropy.
+      &kExpectedRemainderEntropyAssignments,
+      // High entropy clients assign based on high entropy.
+      // Exclusions by layer below.
+      &kExpectedHighEntropyStudyAssignments,
+  });
+  // Some high entropy clients are excluded from the layer by low entropy.
+  for (int i = 1; i < 6; i++) {
+    for (int les_value : {13, 18}) {
+      expected[i * kMaxEntropy + les_value] = "";
+    }
+  }
+
+  EXPECT_THAT(assignments, ::testing::ElementsAreArray(expected));
+}
+
+TEST(VariationsUniformityTest, LowEntropyLayerLowEntropyStudy) {
+  auto assignments =
+      GetUniformityAssignments(LayerStudySeed({.force_low_entropy = true}));
+
+  // Both high and low entropy clients should use remainder entropy.
+  std::vector<std::string> expected = Concat({
+      &kExpectedRemainderEntropyAssignments,
+      &kExpectedRemainderEntropyAssignments,
+      &kExpectedRemainderEntropyAssignments,
+      &kExpectedRemainderEntropyAssignments,
+      &kExpectedRemainderEntropyAssignments,
+      &kExpectedRemainderEntropyAssignments,
+  });
+  EXPECT_THAT(assignments, ::testing::ElementsAreArray(expected));
+}
+
+// We should get the same assignments for clients that have no high entropy.
+// This should be true for both types of layer entropy.
+TEST(VariationsUniformityTest, DefaultEntropyLayerDefaultEntropyStudy) {
+  auto assignments = GetUniformityAssignments(
+      LayerStudySeed({.force_low_entropy_layer = false}));
+
+  std::vector<std::string> expected = Concat({
+      // Low entropy clients assign based on remainder entropy.
+      &kExpectedRemainderEntropyAssignments,
+      // High entropy clients assign based on high entropy.
+      // Exclusions by layer below.
+      &kExpectedHighEntropyStudyAssignments,
+  });
+  // The following clients are excluded from the layer by high entropy.
+  // This is derived from a sample of the high entropy space, so 6/100 is a
+  // reasonable approximation of the average 10/100.
+  for (int exclusion : {35, 40, 43, 54, 79, 95}) {
+    expected[kMaxEntropy + exclusion] = "";
+  }
+
+  EXPECT_THAT(assignments, ::testing::ElementsAreArray(expected));
+}
+
+}  // namespace variations
\ No newline at end of file
diff --git a/components/variations/variations_layers.cc b/components/variations/variations_layers.cc
index 448d852..d854b8f 100644
--- a/components/variations/variations_layers.cc
+++ b/components/variations/variations_layers.cc
@@ -4,12 +4,32 @@
 
 #include "components/variations/variations_layers.h"
 
+#include <stddef.h>
+#include <stdint.h>
+#include <memory>
+
+#include "base/check_op.h"
 #include "base/metrics/field_trial.h"
+#include "base/metrics/histogram_functions.h"
+#include "components/variations/entropy_provider.h"
 
 namespace variations {
 
 namespace {
 
+enum class InvalidLayerReason {
+  kInvalidId = 0,
+  kNoSlots = 1,
+  kNoMembers = 2,
+  kInvalidEntropyMode = 3,
+  kSlotsDoNotDivideLowEntropyDomain = 4,
+  kMaxValue = kSlotsDoNotDivideLowEntropyDomain,
+};
+
+void LogInvalidLayerReason(InvalidLayerReason reason) {
+  base::UmaHistogramEnumeration("Variations.InvalidLayerReason", reason);
+}
+
 // Iterates through the members of the given layer proto definition, and
 // returns the member which contains that slot (if any).
 const Layer::LayerMember* FindActiveMemberBySlot(uint32_t chosen_slot,
@@ -23,49 +43,171 @@
         return &member;
     }
   }
-
   return nullptr;
 }
 
+// A |value| in the range [0, range).
+struct ValueInRange {
+  uint32_t value;
+  uint32_t range;
+};
+
+// The result of SelectSlot.
+struct SlotSelection {
+  // The slot selected.
+  ValueInRange slot;
+  // The remainder after dividing pseudorandom range to slots.
+  ValueInRange pseudorandom_remainder;
+};
+
+SlotSelection SelectSlot(ValueInRange pseudorandom, uint32_t num_slots) {
+  DCHECK_GT(pseudorandom.range, 0u);
+  DCHECK_GT(num_slots, 0u);
+  DCHECK_EQ(pseudorandom.range % num_slots, 0u);
+  // Since range and num_slots are both non-zero, and num_slots is a divisor of
+  // range, slot_size is also guaranteed to be non-zero.
+  uint32_t slot_size = pseudorandom.range / num_slots;
+  return {
+      .slot =
+          {
+              .value = pseudorandom.value / slot_size,
+              .range = num_slots,
+          },
+      .pseudorandom_remainder =
+          {
+              .value = pseudorandom.value % slot_size,
+              .range = slot_size,
+          },
+  };
+}
+
+ValueInRange CombineRanges(ValueInRange major, ValueInRange minor) {
+  return {
+      .value = major.value * minor.range + minor.value,
+      .range = major.range * minor.range,
+  };
+}
+
+ValueInRange SlotOfMember(const Layer::LayerMember& chosen_member,
+                          uint32_t chosen_slot) {
+  uint32_t slots_in_member = 0;
+  uint32_t slots_in_member_less_than_chosen_slot = 0;
+  for (const Layer::LayerMember::SlotRange& range : chosen_member.slots()) {
+    const uint32_t range_size = range.end() - range.start() + 1;
+    slots_in_member += range_size;
+    if (chosen_slot > range.end()) {
+      slots_in_member_less_than_chosen_slot += range_size;
+    } else if (chosen_slot > range.start()) {
+      slots_in_member_less_than_chosen_slot += chosen_slot - range.start();
+    }
+  }
+  return {
+      .value = slots_in_member_less_than_chosen_slot,
+      .range = slots_in_member,
+  };
+}
+
+// Computes a new entropy provider that can be used for uniform low-entropy
+// randomization of studies in the layer member.
+//
+// The concept here is that the layer "divides" the pseudorandom range into
+// different members, where "which member" is the "quotient", and now we are
+// extracting the "remainder" of that division (as well as the range of the
+// remainder, which will be the domain of the new provider).
+//
+// We define the remainder more specifically as the number of values in the
+// pseudorandom function's range which give the same quotient (member) which are
+// less than the given pseudorandom value. This makes the range of the
+// remainder be the number of values in the range that map to the member.
+//
+// For example if |range| is [0,10) and we have a layer with 5 slots, and
+// member M that contains slots 0 and 3, then there are 4 values in |range|
+// that will activate that member [0,1,6,7], so the |remainder.range| will be 4.
+// If |pseudorandom.value| is 7, then [0,1,6] are less than 7, so the
+// |remainder.value| will be 3.
+//
+// The remainder is undefined for values not actually selected by the member,
+// and this function should not be called with a chosen slot that is not in
+// the member.
+NormalizedMurmurHashEntropyProvider ComputeRemainderEntropy(
+    const Layer::LayerMember& chosen_member,
+    SlotSelection selection) {
+  ValueInRange slot_of_member =
+      SlotOfMember(chosen_member, selection.slot.value);
+  ValueInRange remainder =
+      CombineRanges(slot_of_member, selection.pseudorandom_remainder);
+  return NormalizedMurmurHashEntropyProvider(remainder.value, remainder.range);
+}
+
 }  // namespace
 
 VariationsLayers::VariationsLayers(const VariationsSeed& seed,
-                                   const EntropyProviders& entropy_providers) {
+                                   const EntropyProviders& entropy_providers)
+    : nil_entropy(0, 1) {
   // TODO(crbug.com/1154033): Support a way to expire old/unused layers so they
   // no longer get processed by the clients.
   for (const Layer& layer_proto : seed.layers())
     ConstructLayer(entropy_providers, layer_proto);
 }
 
-VariationsLayers::VariationsLayers() = default;
+VariationsLayers::VariationsLayers() : nil_entropy(0, 1) {}
 
 VariationsLayers::~VariationsLayers() = default;
 
 void VariationsLayers::ConstructLayer(const EntropyProviders& entropy_providers,
                                       const Layer& layer_proto) {
-  if (layer_proto.id() == 0 || layer_proto.num_slots() == 0 ||
-      layer_proto.members_size() == 0) {
+  if (layer_proto.id() == 0) {
+    LogInvalidLayerReason(InvalidLayerReason::kInvalidId);
+    return;
+  }
+  if (layer_proto.num_slots() == 0) {
+    LogInvalidLayerReason(InvalidLayerReason::kNoSlots);
+    return;
+  }
+  if (layer_proto.members_size() == 0) {
+    LogInvalidLayerReason(InvalidLayerReason::kNoMembers);
     return;
   }
 
   if (layer_proto.entropy_mode() != Layer::LOW &&
       layer_proto.entropy_mode() != Layer::DEFAULT) {
+    LogInvalidLayerReason(InvalidLayerReason::kInvalidEntropyMode);
     return;
   }
 
+  // Using the size of the domain as the output range maximizes the number of
+  // possible pseudorandom outputs when using the low entropy source.
+  size_t range = entropy_providers.low_entropy_domain();
+  if (range % layer_proto.num_slots() != 0) {
+    // We can't support uniform selection on layers with a slot count that
+    // doesn't divide the low entropy range, so don't support them at all.
+    LogInvalidLayerReason(
+        InvalidLayerReason::kSlotsDoNotDivideLowEntropyDomain);
+    return;
+  }
   const auto& entropy_provider = (layer_proto.entropy_mode() != Layer::LOW)
                                      ? entropy_providers.default_entropy()
                                      : entropy_providers.low_entropy();
-
-  uint32_t chosen_slot = entropy_provider.GetPseudorandomValue(
-      layer_proto.salt(), layer_proto.num_slots());
-
-  const auto* chosen_member = FindActiveMemberBySlot(chosen_slot, layer_proto);
-  if (!chosen_member)
+  ValueInRange pseudorandom = {
+      .value = entropy_provider.GetPseudorandomValue(layer_proto.salt(), range),
+      .range = static_cast<uint32_t>(range),
+  };
+  SlotSelection selection = SelectSlot(pseudorandom, layer_proto.num_slots());
+  const auto* chosen_member =
+      FindActiveMemberBySlot(selection.slot.value, layer_proto);
+  if (!chosen_member) {
+    // No member is active for the chosen slot.
     return;
+  }
+
+  // Store the active member info, along with the remainder entropy.
   active_member_for_layer_.emplace(
-      layer_proto.id(), LayerInfo{.active_member_id = chosen_member->id(),
-                                  .entropy_mode = layer_proto.entropy_mode()});
+      layer_proto.id(), LayerInfo{
+                            .active_member_id = chosen_member->id(),
+                            .entropy_mode = layer_proto.entropy_mode(),
+                            .remainder_entropy = ComputeRemainderEntropy(
+                                *chosen_member, selection),
+                        });
 }
 
 bool VariationsLayers::IsLayerMemberActive(uint32_t layer_id,
@@ -87,4 +229,15 @@
   return layer_iter->second.entropy_mode == Layer::DEFAULT;
 }
 
+const base::FieldTrial::EntropyProvider& VariationsLayers::GetRemainderEntropy(
+    uint32_t layer_id) const {
+  auto layer_iter = active_member_for_layer_.find(layer_id);
+  if (layer_iter == active_member_for_layer_.end()) {
+    // TODO(holte): Remove CreateTrialsForStudy fuzzer, then uncomment this.
+    // NOTREACHED();
+    return nil_entropy;
+  }
+  return layer_iter->second.remainder_entropy;
+}
+
 }  // namespace variations
diff --git a/components/variations/variations_layers.h b/components/variations/variations_layers.h
index 15901da2..4bf3cb7 100644
--- a/components/variations/variations_layers.h
+++ b/components/variations/variations_layers.h
@@ -41,16 +41,28 @@
   // not the client _has_ a high entropy source).
   bool ActiveLayerMemberDependsOnHighEntropy(uint32_t layer_id) const;
 
- private:
-  void ConstructLayer(const EntropyProviders& entropy_providers,
-                      const Layer& layer_proto);
+  // Gets an EntropyProvider for low entropy randomization of studies
+  // conditioned on the layer's active member.
+  const base::FieldTrial::EntropyProvider& GetRemainderEntropy(
+      uint32_t layer_id) const;
 
+ private:
   struct LayerInfo {
     // Which layer member is active in the layer.
     uint32_t active_member_id;
     // The type of entropy the layer was configured to use.
     Layer::EntropyMode entropy_mode;
+    // If this layer has an active member, this is the remaining entropy from
+    // that selection, which can be used for uniform randomization of studies
+    // conditioned on that layer member.
+    // See ComputeRemainderEntropy() for details.
+    NormalizedMurmurHashEntropyProvider remainder_entropy;
   };
+
+  void ConstructLayer(const EntropyProviders& entropy_providers,
+                      const Layer& layer_proto);
+
+  NormalizedMurmurHashEntropyProvider nil_entropy;
   std::map<uint32_t, LayerInfo> active_member_for_layer_;
 };
 
diff --git a/components/viz/client/client_resource_provider_unittest.cc b/components/viz/client/client_resource_provider_unittest.cc
index 6ef5098..18893313 100644
--- a/components/viz/client/client_resource_provider_unittest.cc
+++ b/components/viz/client/client_resource_provider_unittest.cc
@@ -29,7 +29,7 @@
   ClientResourceProviderTest()
       : use_gpu_(GetParam()),
         context_provider_(TestContextProvider::Create()),
-        bound_(context_provider_->BindToCurrentThread()) {
+        bound_(context_provider_->BindToCurrentSequence()) {
     DCHECK_EQ(bound_, gpu::ContextResult::kSuccess);
   }
 
diff --git a/components/viz/common/gpu/context_cache_controller.cc b/components/viz/common/gpu/context_cache_controller.cc
index d9b92f6..0e9ce30 100644
--- a/components/viz/common/gpu/context_cache_controller.cc
+++ b/components/viz/common/gpu/context_cache_controller.cc
@@ -34,7 +34,7 @@
 
 ContextCacheController::ContextCacheController(
     gpu::ContextSupport* context_support,
-    scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+    scoped_refptr<base::SequencedTaskRunner> task_runner)
     : context_support_(context_support), task_runner_(std::move(task_runner)) {
   // The |weak_factory_| can only be used from a single thread. We
   // create/destroy this class and run callbacks on a single thread, but we
diff --git a/components/viz/common/gpu/context_cache_controller.h b/components/viz/common/gpu/context_cache_controller.h
index bb8971b..870ea40 100644
--- a/components/viz/common/gpu/context_cache_controller.h
+++ b/components/viz/common/gpu/context_cache_controller.h
@@ -11,6 +11,7 @@
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/task/single_thread_task_runner.h"
 #include "components/viz/common/viz_common_export.h"
 
@@ -48,9 +49,8 @@
   using ScopedVisibility = ScopedToken;
   using ScopedBusy = ScopedToken;
 
-  ContextCacheController(
-      gpu::ContextSupport* context_support,
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+  ContextCacheController(gpu::ContextSupport* context_support,
+                         scoped_refptr<base::SequencedTaskRunner> task_runner);
   virtual ~ContextCacheController();
 
   void SetGrContext(GrDirectContext* gr_context);
@@ -88,7 +88,7 @@
   void InvalidatePendingIdleCallbacks();
 
   raw_ptr<gpu::ContextSupport> context_support_;
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+  scoped_refptr<base::SequencedTaskRunner> task_runner_;
   raw_ptr<GrDirectContext> gr_context_ = nullptr;
 
   std::unique_ptr<ScopedVisibility> held_visibility_;
diff --git a/components/viz/common/gpu/context_cache_controller_unittest.cc b/components/viz/common/gpu/context_cache_controller_unittest.cc
index d290615c..ba73ca9 100644
--- a/components/viz/common/gpu/context_cache_controller_unittest.cc
+++ b/components/viz/common/gpu/context_cache_controller_unittest.cc
@@ -163,7 +163,7 @@
   auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
   ContextCacheController cache_controller(&context_support, task_runner);
   auto context_provider = TestContextProvider::Create();
-  context_provider->BindToCurrentThread();
+  context_provider->BindToCurrentSequence();
   auto* gr_context = context_provider->GrContext();
   cache_controller.SetGrContext(gr_context);
 
diff --git a/components/viz/common/gpu/context_provider.h b/components/viz/common/gpu/context_provider.h
index 1459d62..25b76d1 100644
--- a/components/viz/common/gpu/context_provider.h
+++ b/components/viz/common/gpu/context_provider.h
@@ -66,10 +66,10 @@
   // from the same thread unless the function has some explicitly specified
   // rules for access on a different thread. See SetupLockOnMainThread(), which
   // can be used to provide access from multiple threads.
-  virtual gpu::ContextResult BindToCurrentThread() = 0;
+  virtual gpu::ContextResult BindToCurrentSequence() = 0;
 
   // Adds/removes an observer to be called when the context is lost. AddObserver
-  // should be called before BindToCurrentThread from the same thread that the
+  // should be called before BindToCurrentSequence from the same thread that the
   // context is bound to, or any time while the lock is acquired after checking
   // for context loss.
   // NOTE: Implementations must avoid post-tasking the to the observer directly
diff --git a/components/viz/common/gpu/raster_context_provider.h b/components/viz/common/gpu/raster_context_provider.h
index 5f9719ed..adf8aec 100644
--- a/components/viz/common/gpu/raster_context_provider.h
+++ b/components/viz/common/gpu/raster_context_provider.h
@@ -63,16 +63,16 @@
   virtual void AddRef() const = 0;
   virtual void Release() const = 0;
 
-  // Bind the 3d context to the current thread. This should be called before
+  // Bind the 3d context to the current sequence. This should be called before
   // accessing the contexts. Calling it more than once should have no effect.
   // Once this function has been called, the class should only be accessed
-  // from the same thread unless the function has some explicitly specified
-  // rules for access on a different thread. See SetupLockOnMainThread(), which
-  // can be used to provide access from multiple threads.
-  virtual gpu::ContextResult BindToCurrentThread() = 0;
+  // from the same sequence unless the function has some explicitly specified
+  // rules for access on a different sequence. See SetupLockOnMainThread(),
+  // which can be used to provide access from multiple threads.
+  virtual gpu::ContextResult BindToCurrentSequence() = 0;
 
   // Adds/removes an observer to be called when the context is lost. AddObserver
-  // should be called before BindToCurrentThread from the same thread that the
+  // should be called before BindToCurrentSequence from the same thread that the
   // context is bound to, or any time while the lock is acquired after checking
   // for context loss.
   // NOTE: Implementations must avoid post-tasking the to the observer directly
diff --git a/components/viz/common/quads/render_pass_io.cc b/components/viz/common/quads/render_pass_io.cc
index ddad591b..8a722ee 100644
--- a/components/viz/common/quads/render_pass_io.cc
+++ b/components/viz/common/quads/render_pass_io.cc
@@ -988,12 +988,10 @@
   return list;
 }
 
-bool DrawQuadResourcesFromList(const base::Value& list,
+bool DrawQuadResourcesFromList(const base::Value::List& list,
                                DrawQuad::Resources* resources) {
   DCHECK(resources);
-  if (!list.is_list())
-    return false;
-  size_t size = list.GetList().size();
+  size_t size = list.size();
   if (size == 0u) {
     resources->count = 0u;
     return true;
@@ -1001,13 +999,13 @@
   if (size > DrawQuad::Resources::kMaxResourceIdCount)
     return false;
   for (size_t ii = 0; ii < size; ++ii) {
-    if (!list.GetList()[ii].is_int())
+    if (!list[ii].is_int())
       return false;
   }
 
   resources->count = static_cast<uint32_t>(size);
   for (size_t ii = 0; ii < size; ++ii) {
-    resources->ids[ii] = ResourceId(list.GetList()[ii].GetInt());
+    resources->ids[ii] = ResourceId(list[ii].GetInt());
   }
   return true;
 }
@@ -1148,7 +1146,7 @@
   absl::optional<bool> needs_blending = dict.FindBool("needs_blending");
   absl::optional<int> shared_quad_state_index =
       dict.FindInt("shared_quad_state_index");
-  const base::Value* resources = dict_value.FindListKey("resources");
+  const base::Value::List* resources = dict.FindList("resources");
   if (!material || !rect || !visible_rect || !needs_blending ||
       !shared_quad_state_index || !resources) {
     return absl::nullopt;
diff --git a/components/viz/service/display/display_resource_provider_skia_unittest.cc b/components/viz/service/display/display_resource_provider_skia_unittest.cc
index ea23b7d..7533035 100644
--- a/components/viz/service/display/display_resource_provider_skia_unittest.cc
+++ b/components/viz/service/display/display_resource_provider_skia_unittest.cc
@@ -78,7 +78,7 @@
  public:
   DisplayResourceProviderSkiaTest() {
     child_context_provider_ = TestContextProvider::Create();
-    child_context_provider_->BindToCurrentThread();
+    child_context_provider_->BindToCurrentSequence();
     child_resource_provider_ = std::make_unique<ClientResourceProvider>();
   }
 
diff --git a/components/viz/service/display/display_unittest.cc b/components/viz/service/display/display_unittest.cc
index 50d89471..57081cc 100644
--- a/components/viz/service/display/display_unittest.cc
+++ b/components/viz/service/display/display_unittest.cc
@@ -182,7 +182,7 @@
 
   void SetUpGpuDisplay(const RendererSettings& settings) {
     scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
-    provider->BindToCurrentThread();
+    provider->BindToCurrentSequence();
     std::unique_ptr<FakeSkiaOutputSurface> skia_output_surface =
         FakeSkiaOutputSurface::Create3d(std::move(provider));
     skia_output_surface_ = skia_output_surface.get();
@@ -5045,7 +5045,7 @@
  public:
   void SetUpGpuDisplaySkiaWithPlatformInk(const RendererSettings& settings) {
     scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
-    provider->BindToCurrentThread();
+    provider->BindToCurrentSequence();
     std::unique_ptr<FakeSkiaOutputSurface> skia_output_surface =
         FakeSkiaOutputSurface::Create3d(std::move(provider));
     // Set the delegated ink capability on the output surface to true so that
diff --git a/components/viz/service/display/overlay_ca_unittest.cc b/components/viz/service/display/overlay_ca_unittest.cc
index 8835f37..6b75ed8a 100644
--- a/components/viz/service/display/overlay_ca_unittest.cc
+++ b/components/viz/service/display/overlay_ca_unittest.cc
@@ -182,7 +182,7 @@
                                        output_surface_.get());
 
     child_provider_ = TestContextProvider::Create();
-    child_provider_->BindToCurrentThread();
+    child_provider_->BindToCurrentSequence();
     child_resource_provider_ = std::make_unique<ClientResourceProvider>();
 
     overlay_processor_ = std::make_unique<CATestOverlayProcessor>();
diff --git a/components/viz/service/display/overlay_candidate_factory_unittest.cc b/components/viz/service/display/overlay_candidate_factory_unittest.cc
index 900b375b..690c18b 100644
--- a/components/viz/service/display/overlay_candidate_factory_unittest.cc
+++ b/components/viz/service/display/overlay_candidate_factory_unittest.cc
@@ -36,7 +36,7 @@
     scoped_refptr<ContextProvider> child_context_provider =
         TestContextProvider::Create();
 
-    child_context_provider->BindToCurrentThread();
+    child_context_provider->BindToCurrentSequence();
 
     auto resource = TransferableResource::MakeGpu(
         gpu::Mailbox::GenerateForSharedImage(), GL_LINEAR, GL_TEXTURE_2D,
diff --git a/components/viz/service/display/overlay_dc_unittest.cc b/components/viz/service/display/overlay_dc_unittest.cc
index eb1d48e..7f4507e 100644
--- a/components/viz/service/display/overlay_dc_unittest.cc
+++ b/components/viz/service/display/overlay_dc_unittest.cc
@@ -54,7 +54,7 @@
  public:
   static std::unique_ptr<MockDCLayerOutputSurface> Create() {
     auto provider = TestContextProvider::Create();
-    provider->BindToCurrentThread();
+    provider->BindToCurrentSequence();
     return std::make_unique<MockDCLayerOutputSurface>(std::move(provider));
   }
 
@@ -206,7 +206,7 @@
                                        output_surface_.get());
 
     child_provider_ = TestContextProvider::Create();
-    child_provider_->BindToCurrentThread();
+    child_provider_->BindToCurrentSequence();
     child_resource_provider_ = std::make_unique<ClientResourceProvider>();
 
     overlay_processor_ =
diff --git a/components/viz/service/display/overlay_unittest.cc b/components/viz/service/display/overlay_unittest.cc
index 64025d2..f3f1f9f 100644
--- a/components/viz/service/display/overlay_unittest.cc
+++ b/components/viz/service/display/overlay_unittest.cc
@@ -697,7 +697,7 @@
                                        output_surface_.get());
 
     child_provider_ = TestContextProvider::Create();
-    child_provider_->BindToCurrentThread();
+    child_provider_->BindToCurrentSequence();
     child_resource_provider_ = std::make_unique<ClientResourceProvider>();
 
     overlay_processor_ = std::make_unique<OverlayProcessorType>();
diff --git a/components/viz/service/display/renderer_perftest.cc b/components/viz/service/display/renderer_perftest.cc
index 0702bf7..632b69c 100644
--- a/components/viz/service/display/renderer_perftest.cc
+++ b/components/viz/service/display/renderer_perftest.cc
@@ -259,7 +259,7 @@
     child_context_provider_ =
         base::MakeRefCounted<TestInProcessContextProvider>(
             TestContextType::kGLES2, /*support_locking=*/false);
-    child_context_provider_->BindToCurrentThread();
+    child_context_provider_->BindToCurrentSequence();
     child_resource_provider_ = std::make_unique<ClientResourceProvider>();
 
     auto skia_deps = std::make_unique<SkiaOutputSurfaceDependencyImpl>(
diff --git a/components/viz/test/fake_skia_output_surface.h b/components/viz/test/fake_skia_output_surface.h
index 2ab2739..b9a97964 100644
--- a/components/viz/test/fake_skia_output_surface.h
+++ b/components/viz/test/fake_skia_output_surface.h
@@ -26,7 +26,7 @@
  public:
   static std::unique_ptr<FakeSkiaOutputSurface> Create3d() {
     auto provider = TestContextProvider::Create();
-    provider->BindToCurrentThread();
+    provider->BindToCurrentSequence();
     return base::WrapUnique(new FakeSkiaOutputSurface(std::move(provider)));
   }
 
diff --git a/components/viz/test/test_context_provider.cc b/components/viz/test/test_context_provider.cc
index 62de87e..3448c40 100644
--- a/components/viz/test/test_context_provider.cc
+++ b/components/viz/test/test_context_provider.cc
@@ -292,7 +292,7 @@
       /*support_locking=*/true);
 
   // Worker contexts are bound to the thread they are created on.
-  auto result = worker_context_provider->BindToCurrentThread();
+  auto result = worker_context_provider->BindToCurrentSequence();
   if (result != gpu::ContextResult::kSuccess)
     return nullptr;
   return worker_context_provider;
@@ -392,7 +392,7 @@
   base::RefCountedThreadSafe<TestContextProvider>::Release();
 }
 
-gpu::ContextResult TestContextProvider::BindToCurrentThread() {
+gpu::ContextResult TestContextProvider::BindToCurrentSequence() {
   // This is called on the thread the context will be used.
   DCHECK(context_thread_checker_.CalledOnValidThread());
 
diff --git a/components/viz/test/test_context_provider.h b/components/viz/test/test_context_provider.h
index 25c9f99..5e0505e9 100644
--- a/components/viz/test/test_context_provider.h
+++ b/components/viz/test/test_context_provider.h
@@ -129,7 +129,7 @@
   static scoped_refptr<TestContextProvider> Create(
       std::string additional_extensions = std::string());
   // Creates a worker context provider that can be used on any thread. This is
-  // equivalent to: Create(); BindToCurrentThread().
+  // equivalent to: Create(); BindToCurrentSequence().
   static scoped_refptr<TestContextProvider> CreateWorker();
   static scoped_refptr<TestContextProvider> CreateWorker(
       std::unique_ptr<TestContextSupport> support);
@@ -156,7 +156,7 @@
   // ContextProvider / RasterContextProvider implementation.
   void AddRef() const override;
   void Release() const override;
-  gpu::ContextResult BindToCurrentThread() override;
+  gpu::ContextResult BindToCurrentSequence() override;
   const gpu::Capabilities& ContextCapabilities() const override;
   const gpu::GpuFeatureInfo& GetGpuFeatureInfo() const override;
   gpu::gles2::GLES2Interface* ContextGL() override;
diff --git a/components/viz/test/test_in_process_context_provider.cc b/components/viz/test/test_in_process_context_provider.cc
index 47eba3cf..51eecdd 100644
--- a/components/viz/test/test_in_process_context_provider.cc
+++ b/components/viz/test/test_in_process_context_provider.cc
@@ -85,7 +85,7 @@
   base::RefCountedThreadSafe<TestInProcessContextProvider>::Release();
 }
 
-gpu::ContextResult TestInProcessContextProvider::BindToCurrentThread() {
+gpu::ContextResult TestInProcessContextProvider::BindToCurrentSequence() {
   auto* holder = TestGpuServiceHolder::GetInstance();
 
   if (type_ == TestContextType::kGLES2) {
diff --git a/components/viz/test/test_in_process_context_provider.h b/components/viz/test/test_in_process_context_provider.h
index 9efeeb4..4fcc80a 100644
--- a/components/viz/test/test_in_process_context_provider.h
+++ b/components/viz/test/test_in_process_context_provider.h
@@ -58,7 +58,7 @@
   // ContextProvider / RasterContextProvider implementation.
   void AddRef() const override;
   void Release() const override;
-  gpu::ContextResult BindToCurrentThread() override;
+  gpu::ContextResult BindToCurrentSequence() override;
   gpu::gles2::GLES2Interface* ContextGL() override;
   gpu::raster::RasterInterface* RasterInterface() override;
   gpu::ContextSupport* ContextSupport() override;
diff --git a/components/webxr/mailbox_to_surface_bridge_impl.cc b/components/webxr/mailbox_to_surface_bridge_impl.cc
index 933a587..f879991a 100644
--- a/components/webxr/mailbox_to_surface_bridge_impl.cc
+++ b/components/webxr/mailbox_to_surface_bridge_impl.cc
@@ -189,7 +189,7 @@
 }
 
 void MailboxToSurfaceBridgeImpl::BindContextProviderToCurrentThread() {
-  auto result = context_provider_->BindToCurrentThread();
+  auto result = context_provider_->BindToCurrentSequence();
   if (result != gpu::ContextResult::kSuccess) {
     DLOG(ERROR) << "Failed to init viz::ContextProvider";
     return;
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index e74b0020..716e4de 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -2399,8 +2399,6 @@
 
   if (is_win) {
     sources += [
-      "accessibility/accessibility_tree_formatter_win.cc",
-      "accessibility/accessibility_tree_formatter_win.h",
       "accessibility/browser_accessibility_com_win.cc",
       "accessibility/browser_accessibility_com_win.h",
       "accessibility/browser_accessibility_manager_win.cc",
diff --git a/content/browser/back_forward_cache_browsertest.cc b/content/browser/back_forward_cache_browsertest.cc
index fd0c5a4..f105c60 100644
--- a/content/browser/back_forward_cache_browsertest.cc
+++ b/content/browser/back_forward_cache_browsertest.cc
@@ -441,11 +441,29 @@
  public:
   explicit ThemeColorObserver(WebContents* contents)
       : WebContentsObserver(contents) {}
-  void DidChangeThemeColor() override { observed_ = true; }
+
+  // Can only be called once.
+  bool WaitUntilThemeColorChange() {
+    CHECK(!loop_);
+    loop_ = std::make_unique<base::RunLoop>();
+    if (observed_) {
+      return true;
+    }
+    loop_->Run();
+    return observed_;
+  }
+
+  void DidChangeThemeColor() override {
+    observed_ = true;
+    if (loop_) {
+      loop_->Quit();
+    }
+  }
 
   bool did_fire() const { return observed_; }
 
  private:
+  std::unique_ptr<base::RunLoop> loop_;
   bool observed_ = false;
 };
 
@@ -980,15 +998,15 @@
   GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));
 
   // 1) Navigate to A.
-  EXPECT_TRUE(NavigateToURL(shell(), url_a));
+  ASSERT_TRUE(NavigateToURL(shell(), url_a));
   WaitForFirstVisuallyNonEmptyPaint(shell()->web_contents());
   RenderFrameHostImpl* rfh_a = current_frame_host();
   RenderFrameDeletedObserver delete_observer_rfh_a(rfh_a);
 
   // 2) Navigate to B.
-  EXPECT_TRUE(NavigateToURL(shell(), url_b));
+  ASSERT_TRUE(NavigateToURL(shell(), url_b));
   ASSERT_FALSE(delete_observer_rfh_a.deleted());
-  EXPECT_TRUE(rfh_a->IsInBackForwardCache());
+  ASSERT_TRUE(rfh_a->IsInBackForwardCache());
   WaitForFirstVisuallyNonEmptyPaint(shell()->web_contents());
 
   // 3) Navigate to back to A.
@@ -1006,21 +1024,19 @@
   GURL url_a(embedded_test_server()->GetURL("a.com", "/theme_color.html"));
   GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));
 
-  EXPECT_TRUE(NavigateToURL(shell(), url_a));
+  ASSERT_TRUE(NavigateToURL(shell(), url_a));
   WaitForFirstVisuallyNonEmptyPaint(web_contents());
-  RenderFrameHostImpl* rfh_a = current_frame_host();
-  RenderFrameDeletedObserver delete_observer_rfh_a(rfh_a);
+  RenderFrameHostImplWrapper rfh_a(current_frame_host());
   EXPECT_EQ(web_contents()->GetThemeColor(), 0xFFFF0000u);
 
-  EXPECT_TRUE(NavigateToURL(shell(), url_b));
+  ASSERT_TRUE(NavigateToURL(shell(), url_b));
   WaitForFirstVisuallyNonEmptyPaint(web_contents());
-  ASSERT_FALSE(delete_observer_rfh_a.deleted());
-  EXPECT_TRUE(rfh_a->IsInBackForwardCache());
+  ASSERT_TRUE(rfh_a->IsInBackForwardCache());
   EXPECT_EQ(web_contents()->GetThemeColor(), absl::nullopt);
 
   ThemeColorObserver observer(web_contents());
   ASSERT_TRUE(HistoryGoBack(web_contents()));
-  EXPECT_TRUE(observer.did_fire());
+  ASSERT_TRUE(observer.WaitUntilThemeColorChange());
   EXPECT_EQ(web_contents()->GetThemeColor(), 0xFFFF0000u);
 }
 
diff --git a/content/browser/compositor/test/test_image_transport_factory.cc b/content/browser/compositor/test/test_image_transport_factory.cc
index d619971..e16be463 100644
--- a/content/browser/compositor/test/test_image_transport_factory.cc
+++ b/content/browser/compositor/test/test_image_transport_factory.cc
@@ -63,7 +63,7 @@
   constexpr bool kSupportsLocking = false;
   shared_main_context_provider_ = ui::InProcessContextProvider::CreateOffscreen(
       &gpu_memory_buffer_manager_, &image_factory_, kSupportsLocking);
-  auto result = shared_main_context_provider_->BindToCurrentThread();
+  auto result = shared_main_context_provider_->BindToCurrentSequence();
   if (result != gpu::ContextResult::kSuccess)
     shared_main_context_provider_ = nullptr;
 
diff --git a/content/browser/compositor/viz_process_transport_factory.cc b/content/browser/compositor/viz_process_transport_factory.cc
index 4c5bf122..034f957 100644
--- a/content/browser/compositor/viz_process_transport_factory.cc
+++ b/content/browser/compositor/viz_process_transport_factory.cc
@@ -498,7 +498,7 @@
     // Don't observer context loss on |worker_context_provider_wrapper_| here,
     // that is already observed by LayerTreeFrameSink. The lost context will
     // be caught when recreating LayerTreeFrameSink(s).
-    auto context_result = worker_context_provider->BindToCurrentThread();
+    auto context_result = worker_context_provider->BindToCurrentSequence();
     if (context_result != gpu::ContextResult::kSuccess)
       return context_result;
 
@@ -528,7 +528,7 @@
         viz::command_buffer_metrics::ContextType::BROWSER_MAIN_THREAD);
     main_context_provider_->SetDefaultTaskRunner(resize_task_runner_);
 
-    auto context_result = main_context_provider_->BindToCurrentThread();
+    auto context_result = main_context_provider_->BindToCurrentSequence();
     if (context_result != gpu::ContextResult::kSuccess) {
       main_context_provider_.reset();
       return context_result;
diff --git a/content/browser/devtools/devtools_url_loader_interceptor.cc b/content/browser/devtools/devtools_url_loader_interceptor.cc
index f19138f9..484c937 100644
--- a/content/browser/devtools/devtools_url_loader_interceptor.cc
+++ b/content/browser/devtools/devtools_url_loader_interceptor.cc
@@ -259,6 +259,96 @@
   network::URLLoaderCompletionStatus status;
 };
 
+class HeadersOverride {
+ public:
+  static std::unique_ptr<HeadersOverride> SaveAndOverride(
+      network::ResourceRequest& request,
+      DevToolsURLLoaderInterceptor::Modifications::HeadersVector
+          modified_headers) {
+    std::unique_ptr<HeadersOverride> instance(new HeadersOverride(request));
+    DCHECK(request.headers.IsEmpty());
+
+    for (const auto& entry : modified_headers) {
+      if (base::EqualsCaseInsensitiveASCII(entry.first,
+                                           net::HttpRequestHeaders::kReferer)) {
+        request.referrer = GURL(entry.second);
+        request.referrer_policy = net::ReferrerPolicy::NEVER_CLEAR;
+      } else {
+        request.headers.SetHeader(entry.first, entry.second);
+      }
+    }
+    return instance;
+  }
+
+  static void Revert(std::unique_ptr<HeadersOverride> instance) {
+    instance->request_.headers = std::move(instance->original_headers_);
+    instance->request_.referrer = instance->original_referrer_;
+    instance->request_.referrer_policy = instance->original_referrer_policy_;
+  }
+
+  static void RevertForFollowRedirect(
+      std::unique_ptr<HeadersOverride> instance,
+      std::vector<std::string>& removed_headers,
+      net::HttpRequestHeaders& modified_headers) {
+    ComputeModifications(instance->request_.headers,
+                         instance->original_headers_, removed_headers,
+                         modified_headers);
+    Revert(std::move(instance));
+  }
+
+  // If the higher-level URLLoader performs any header modifications when
+  // calling `FollowRedirect()`, apply those to "original" headers, so these get
+  // applied during Revert.
+  void ApplyModifications(const std::vector<std::string>& removed_headers,
+                          const net::HttpRequestHeaders& modified_headers) {
+    for (const auto& entry : removed_headers)
+      original_headers_.RemoveHeader(entry);
+    original_headers_.MergeFrom(modified_headers);
+  }
+
+  void ModificationsForRedirect(std::vector<std::string>& removed_headers,
+                                net::HttpRequestHeaders& modified_headers) {
+    ComputeModifications(original_headers_, request_.headers, removed_headers,
+                         modified_headers);
+  }
+
+ private:
+  explicit HeadersOverride(network::ResourceRequest& request)
+      : request_(request),
+        original_headers_(std::move(request.headers)),
+        original_referrer_(request.referrer),
+        original_referrer_policy_(request.referrer_policy) {}
+
+  // Compute `remove_headers` and `modified_headers` that are needed
+  // to turn `a` into `b`.
+  static void ComputeModifications(const net::HttpRequestHeaders& a,
+                                   const net::HttpRequestHeaders& b,
+                                   std::vector<std::string>& removed_headers,
+                                   net::HttpRequestHeaders& modified_headers) {
+    DCHECK(removed_headers.empty());
+    DCHECK(modified_headers.IsEmpty());
+
+    std::map<std::string, std::string> old_headers;
+    for (const auto& entry : a.GetHeaderVector())
+      old_headers.insert({entry.key, entry.value});
+
+    for (const auto& entry : b.GetHeaderVector()) {
+      auto it = old_headers.find(entry.key);
+      if (it == old_headers.end() || it->second != entry.value)
+        modified_headers.SetHeader(entry.key, entry.value);
+      if (it != old_headers.end())
+        old_headers.erase(it);
+    }
+    for (const auto& entry : old_headers)
+      removed_headers.push_back(entry.first);
+  }
+
+  network::ResourceRequest& request_;
+  net::HttpRequestHeaders original_headers_;
+  GURL original_referrer_;
+  net::ReferrerPolicy original_referrer_policy_;
+};
+
 }  // namespace
 
 class InterceptionJob : public network::mojom::URLLoaderClient,
@@ -441,6 +531,9 @@
   // current request URL. Tracked for the purpose of computing the proper
   // SameSite cookies to return, which depends on the redirect chain.
   std::vector<GURL> url_chain_;
+  // In case headers are overridden, keep the original and restore them
+  // upon a redirect, so that overrides don't stick across redirects.
+  std::unique_ptr<HeadersOverride> headers_override_;
 };
 
 void DevToolsURLLoaderInterceptor::CreateJob(
@@ -951,17 +1044,21 @@
 
   if (state_ == State::kFollowRedirect) {
     if (!modifications->modified_url.isJust()) {
-      // TODO(caseq): report error modifications other than headers are present.
+      // TODO(caseq): report error if other modifications are present.
       state_ = State::kRequestSent;
       std::vector<std::string> removed_headers;
       net::HttpRequestHeaders modified_headers;
-      if (modifications->modified_headers) {
-        for (const auto& entry : *modifications->modified_headers) {
-          if (entry.second.empty())
-            removed_headers.push_back(entry.first);
-          else
-            modified_headers.SetHeader(entry.first, entry.second);
+      if (!modifications->modified_headers) {
+        if (headers_override_) {
+          HeadersOverride::RevertForFollowRedirect(
+              std::move(headers_override_), removed_headers, modified_headers);
         }
+      } else {
+        headers_override_ = HeadersOverride::SaveAndOverride(
+            create_loader_params_->request,
+            std::move(*modifications->modified_headers));
+        headers_override_->ModificationsForRedirect(removed_headers,
+                                                    modified_headers);
       }
       loader_->FollowRedirect(removed_headers, modified_headers, {},
                               absl::nullopt);
@@ -1047,16 +1144,9 @@
   }
 
   if (modifications->modified_headers) {
-    request->headers.Clear();
-    for (const auto& entry : *modifications->modified_headers) {
-      if (base::EqualsCaseInsensitiveASCII(entry.first,
-                                           net::HttpRequestHeaders::kReferer)) {
-        request->referrer = GURL(entry.second);
-        request->referrer_policy = net::ReferrerPolicy::NEVER_CLEAR;
-      } else {
-        request->headers.SetHeader(entry.first, entry.second);
-      }
-    }
+    DCHECK(!headers_override_);
+    headers_override_ = HeadersOverride::SaveAndOverride(
+        *request, std::move(*modifications->modified_headers));
   }
 }
 
@@ -1326,7 +1416,6 @@
     result->response_headers = head->headers;
   if (!redirected_request_id_.empty())
     result->redirected_request_id = redirected_request_id_;
-
   return result;
 }
 
@@ -1447,6 +1536,9 @@
 
   url_chain_.push_back(create_loader_params_->request.url);
 
+  if (headers_override_)
+    headers_override_->ApplyModifications(removed_headers, modified_headers);
+
   if (interceptor_) {
     redirected_request_id_ = current_id_;
     // Pretend that each redirect hop is a new request -- this is for
@@ -1458,7 +1550,19 @@
   }
   if (state_ == State::kRedirectReceived) {
     state_ = State::kRequestSent;
-    loader_->FollowRedirect(removed_headers, modified_headers,
+    if (!headers_override_) {
+      loader_->FollowRedirect(removed_headers, modified_headers,
+                              modified_cors_exempt_headers,
+                              absl::nullopt /* new_url */);
+      return;
+    }
+    // Re-compute removed and modified headers while taking original
+    // restored header values into account;
+    std::vector<std::string> removals;
+    net::HttpRequestHeaders modifications;
+    HeadersOverride::RevertForFollowRedirect(std::move(headers_override_),
+                                             removals, modifications);
+    loader_->FollowRedirect(removals, modifications,
                             modified_cors_exempt_headers,
                             absl::nullopt /* new_url */);
     return;
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc
index d426b71..ab6b74f 100644
--- a/content/browser/download/download_manager_impl.cc
+++ b/content/browser/download/download_manager_impl.cc
@@ -92,10 +92,6 @@
 #include "third_party/blink/public/common/storage_key/storage_key.h"
 #include "url/origin.h"
 
-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
-#include "base/nix/xdg_util.h"
-#endif
-
 namespace content {
 namespace {
 
@@ -219,13 +215,6 @@
   }
 };
 
-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
-base::FilePath GetTemporaryDownloadDirectory() {
-  std::unique_ptr<base::Environment> env(base::Environment::Create());
-  return base::nix::GetXDGDirectory(env.get(), "XDG_DATA_HOME", ".local/share");
-}
-#endif
-
 std::unique_ptr<network::PendingSharedURLLoaderFactory>
 CreatePendingSharedURLLoaderFactory(StoragePartitionImpl* storage_partition,
                                     RenderFrameHost* rfh,
@@ -655,13 +644,6 @@
 
 base::FilePath DownloadManagerImpl::GetDefaultDownloadDirectory() {
   base::FilePath default_download_directory;
-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
-  // TODO(thomasanderson,crbug.com/784010): Remove this when all Linux
-  // distros with versions of GTK lower than 3.14.7 are no longer
-  // supported.  This should happen when support for Ubuntu Trusty and
-  // Debian Jessie are removed.
-  default_download_directory = GetTemporaryDownloadDirectory();
-#endif
 
   if (delegate_ && default_download_directory.empty()) {
     base::FilePath website_save_directory;  // Unused
diff --git a/content/browser/download/download_manager_impl_unittest.cc b/content/browser/download/download_manager_impl_unittest.cc
index 9c98bff..8115bc0a2 100644
--- a/content/browser/download/download_manager_impl_unittest.cc
+++ b/content/browser/download/download_manager_impl_unittest.cc
@@ -614,16 +614,7 @@
   EXPECT_CALL(GetMockDownloadManagerDelegate(), GetNextId_(_))
       .WillOnce(RunOnceCallback<0>(local_id));
 
-  // TODO(thomasanderson,crbug.com/784010): Remove this when all Linux
-  // distros with versions of GTK lower than 3.14.7 are no longer
-  // supported.  This should happen when support for Ubuntu Trusty and
-  // Debian Jessie are removed.
-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
-  // Doing nothing will set the default download directory to null.
-  EXPECT_CALL(GetMockDownloadManagerDelegate(), GetSaveDir(_, _, _)).Times(0);
-#else
   EXPECT_CALL(GetMockDownloadManagerDelegate(), GetSaveDir(_, _, _));
-#endif
 
   EXPECT_CALL(GetMockDownloadManagerDelegate(),
               ApplicationClientIdForFileScanning())
@@ -657,16 +648,7 @@
   EXPECT_CALL(GetMockDownloadManagerDelegate(), GetNextId_(_))
       .WillOnce(RunOnceCallback<0>(download::DownloadItem::kInvalidId));
 
-  // TODO(thomasanderson,crbug.com/784010): Remove this when all Linux
-  // distros with versions of GTK lower than 3.14.7 are no longer
-  // supported.  This should happen when support for Ubuntu Trusty and
-  // Debian Jessie are removed.
-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
-  // Doing nothing will set the default download directory to null.
-  EXPECT_CALL(GetMockDownloadManagerDelegate(), GetSaveDir(_, _, _)).Times(0);
-#else
   EXPECT_CALL(GetMockDownloadManagerDelegate(), GetSaveDir(_, _, _));
-#endif
 
   EXPECT_CALL(GetMockDownloadManagerDelegate(),
               ApplicationClientIdForFileScanning())
diff --git a/content/browser/gpu/gpu_ipc_browsertests.cc b/content/browser/gpu/gpu_ipc_browsertests.cc
index 84b4e50..a292899 100644
--- a/content/browser/gpu/gpu_ipc_browsertests.cc
+++ b/content/browser/gpu/gpu_ipc_browsertests.cc
@@ -67,7 +67,7 @@
 
     provider_ =
         content::GpuBrowsertestCreateContext(std::move(gpu_channel_host));
-    auto result = provider_->BindToCurrentThread();
+    auto result = provider_->BindToCurrentSequence();
     CHECK_EQ(result, gpu::ContextResult::kSuccess);
     gl_ = provider_->ContextGL();
     context_support_ = provider_->ContextSupport();
@@ -211,7 +211,7 @@
   // retain the host after provider is destroyed.
   scoped_refptr<viz::ContextProviderCommandBuffer> provider =
       content::GpuBrowsertestCreateContext(GetGpuChannel());
-  ASSERT_EQ(provider->BindToCurrentThread(), gpu::ContextResult::kSuccess);
+  ASSERT_EQ(provider->BindToCurrentSequence(), gpu::ContextResult::kSuccess);
 
   sk_sp<GrDirectContext> gr_context = sk_ref_sp(provider->GrContext());
 
@@ -261,7 +261,7 @@
   scoped_refptr<viz::ContextProviderCommandBuffer> provider =
       content::GpuBrowsertestCreateContext(GetGpuChannel());
   ContextLostRunLoop run_loop(provider.get());
-  ASSERT_EQ(provider->BindToCurrentThread(), gpu::ContextResult::kSuccess);
+  ASSERT_EQ(provider->BindToCurrentSequence(), gpu::ContextResult::kSuccess);
   GpuProcessHost::CallOnIO(FROM_HERE, GPU_PROCESS_KIND_SANDBOXED,
                            false /* force_create */,
                            base::BindOnce([](GpuProcessHost* host) {
diff --git a/content/browser/media/android/browser_gpu_video_accelerator_factories.cc b/content/browser/media/android/browser_gpu_video_accelerator_factories.cc
index 07f9cf3c..aa2ad99c 100644
--- a/content/browser/media/android/browser_gpu_video_accelerator_factories.cc
+++ b/content/browser/media/android/browser_gpu_video_accelerator_factories.cc
@@ -55,7 +55,7 @@
           automatic_flushes, support_locking, support_grcontext,
           gpu::SharedMemoryLimits::ForMailboxContext(), attributes,
           viz::command_buffer_metrics::ContextType::UNKNOWN);
-  context_provider->BindToCurrentThread();
+  context_provider->BindToCurrentSequence();
 
   auto gpu_factories = std::make_unique<BrowserGpuVideoAcceleratorFactories>(
       std::move(context_provider));
diff --git a/content/browser/native_io/OWNERS b/content/browser/native_io/OWNERS
index 565fba10..136f6d9 100644
--- a/content/browser/native_io/OWNERS
+++ b/content/browser/native_io/OWNERS
@@ -1,6 +1,2 @@
-# Primary
-mkwst@chromium.org
-
-# Secondary
 asully@chromium.org
 ayui@chromium.org
diff --git a/content/browser/preloading/prerender/prerender_browsertest.cc b/content/browser/preloading/prerender/prerender_browsertest.cc
index bc3f284..38b17f6a 100644
--- a/content/browser/preloading/prerender/prerender_browsertest.cc
+++ b/content/browser/preloading/prerender/prerender_browsertest.cc
@@ -4323,7 +4323,7 @@
   test::PrerenderHostObserver prerender1_observer(*web_contents(),
                                                   GetHostForUrl(kPrerender1));
 
-  // Defer the activation until the ongoing initial navigation in preerender
+  // Defer the activation until the ongoing initial navigation in prerender
   // frame tree commits.
   TestActivationManager primary_page_manager(shell()->web_contents(),
                                              kPrerender1);
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc
index d74c2afe..c03805c 100644
--- a/content/browser/renderer_host/compositor_impl_android.cc
+++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -709,7 +709,7 @@
               display_color_spaces_.GetRasterColorSpace(),
               requires_alpha_channel_),
           viz::command_buffer_metrics::ContextType::BROWSER_COMPOSITOR);
-  auto result = context_provider->BindToCurrentThread();
+  auto result = context_provider->BindToCurrentSequence();
 
   if (result == gpu::ContextResult::kFatalFailure) {
     LOG(FATAL) << "Fatal failure in creating offscreen context";
diff --git a/content/browser/renderer_host/compositor_impl_android_browsertest.cc b/content/browser/renderer_host/compositor_impl_android_browsertest.cc
index a1ffd83..bc9d8d3 100644
--- a/content/browser/renderer_host/compositor_impl_android_browsertest.cc
+++ b/content/browser/renderer_host/compositor_impl_android_browsertest.cc
@@ -157,7 +157,7 @@
   auto* compositor = compositor_impl();
   auto context = GpuBrowsertestCreateContext(
       GpuBrowsertestEstablishGpuChannelSyncRunLoop());
-  context->BindToCurrentThread();
+  context->BindToCurrentSequence();
 
   // Run until we've swapped once. At this point we should have a valid frame.
   CompositorSwapRunLoop(compositor_impl()).RunUntilSwap();
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index 3841145..17d58e6 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -8804,24 +8804,6 @@
   parent_->RemoveChild(frame_tree_node_);
 }
 
-void RenderFrameHostImpl::UpdateOpener() {
-  TRACE_EVENT1("navigation", "RenderFrameHostImpl::UpdateOpener",
-               "render_frame_host", this);
-
-  // This frame (the frame whose opener is being updated) might not have had
-  // proxies for the new opener chain in its SiteInstance.  Make sure they
-  // exist.
-  if (frame_tree_node_->opener()) {
-    frame_tree_node_->opener()->render_manager()->CreateOpenerProxies(
-        GetSiteInstance(), frame_tree_node_, browsing_context_state_);
-  }
-
-  auto opener_frame_token =
-      frame_tree_node_->render_manager()->GetOpenerFrameToken(
-          GetSiteInstance()->group());
-  GetAssociatedLocalFrame()->UpdateOpener(opener_frame_token);
-}
-
 void RenderFrameHostImpl::SetFocusedFrame() {
   GetAssociatedLocalFrame()->Focus();
 }
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h
index 559a598..731baa2a 100644
--- a/content/browser/renderer_host/render_frame_host_impl.h
+++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -1268,11 +1268,6 @@
   // callbacks to be invoked before timing out.
   void SetBeforeUnloadTimeoutDelayForTesting(const base::TimeDelta& timeout);
 
-  // Update the frame's opener in the renderer process in response to the
-  // opener being modified (e.g., with window.open or being set to null) in
-  // another renderer process.
-  void UpdateOpener();
-
   // Set this frame as focused in the renderer process.  This supports
   // cross-process window.focus() calls.
   void SetFocusedFrame();
diff --git a/content/browser/renderer_host/render_frame_host_manager.cc b/content/browser/renderer_host/render_frame_host_manager.cc
index d170099..c822c6b 100644
--- a/content/browser/renderer_host/render_frame_host_manager.cc
+++ b/content/browser/renderer_host/render_frame_host_manager.cc
@@ -660,7 +660,7 @@
 
   if (render_frame_host_->GetSiteInstance()->group() !=
       source_site_instance_group) {
-    render_frame_host_->UpdateOpener();
+    UpdateOpener(render_frame_host_.get());
   }
 
   // Notify the speculative RenderFrameHosts as well.  This is necessary in case
@@ -668,7 +668,7 @@
   if (speculative_render_frame_host_ &&
       speculative_render_frame_host_->GetSiteInstance()->group() !=
           source_site_instance_group) {
-    speculative_render_frame_host_->UpdateOpener();
+    UpdateOpener(speculative_render_frame_host_.get());
   }
 }
 
@@ -762,6 +762,26 @@
   return stored_page;
 }
 
+void RenderFrameHostManager::UpdateOpener(
+    RenderFrameHostImpl* render_frame_host) {
+  TRACE_EVENT1("navigation", "RenderFrameHostManager::UpdateOpener",
+               "render_frame_host", render_frame_host);
+
+  // `render_frame_host` (the frame whose opener is being updated) might not
+  // have had proxies for the new opener chain in its SiteInstance.  Make sure
+  // they exist.
+  if (frame_tree_node_->opener()) {
+    frame_tree_node_->opener()->render_manager()->CreateOpenerProxies(
+        render_frame_host->GetSiteInstance(), frame_tree_node_,
+        render_frame_host->browsing_context_state());
+  }
+
+  auto opener_frame_token =
+      GetOpenerFrameToken(render_frame_host->GetSiteInstance()->group());
+  render_frame_host->GetAssociatedLocalFrame()->UpdateOpener(
+      opener_frame_token);
+}
+
 void RenderFrameHostManager::UnloadOldFrame(
     std::unique_ptr<RenderFrameHostImpl> old_render_frame_host) {
   TRACE_EVENT1("navigation", "RenderFrameHostManager::UnloadOldFrame",
diff --git a/content/browser/renderer_host/render_frame_host_manager.h b/content/browser/renderer_host/render_frame_host_manager.h
index a63d43f..43c7ffd 100644
--- a/content/browser/renderer_host/render_frame_host_manager.h
+++ b/content/browser/renderer_host/render_frame_host_manager.h
@@ -891,6 +891,11 @@
   std::unique_ptr<StoredPage> CollectPage(
       std::unique_ptr<RenderFrameHostImpl> main_render_frame_host);
 
+  // Update `render_frame_host`'s opener in the renderer process in response to
+  // the opener being modified (e.g., with window.open or being set to null) in
+  // another renderer process.
+  void UpdateOpener(RenderFrameHostImpl* render_frame_host);
+
   // For use in creating RenderFrameHosts.
   raw_ptr<FrameTreeNode> frame_tree_node_;
 
diff --git a/content/browser/service_worker/service_worker_identifiability_metrics.cc b/content/browser/service_worker/service_worker_identifiability_metrics.cc
index 3fc728c..2ee92b6f 100644
--- a/content/browser/service_worker/service_worker_identifiability_metrics.cc
+++ b/content/browser/service_worker/service_worker_identifiability_metrics.cc
@@ -9,6 +9,8 @@
 #include "services/metrics/public/cpp/delegating_ukm_recorder.h"
 #include "services/metrics/public/cpp/ukm_builders.h"
 #include "third_party/blink/public/common/privacy_budget/identifiability_sample_collector.h"
+#include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h"
+#include "third_party/blink/public/common/privacy_budget/identifiability_study_worker_client_added.h"
 #include "url/gurl.h"
 
 namespace content {
@@ -114,6 +116,13 @@
         .SetClientSourceId(client_ukm_source_id)
         .SetWorkerType(static_cast<int64_t>(WorkerType::kServiceWorker))
         .Record(ukm_recorder);
+
+    if (blink::IdentifiabilityStudySettings::Get()->IsActive()) {
+      blink::IdentifiabilityStudyWorkerClientAdded(version_ukm_source_id)
+          .SetClientSourceId(client_ukm_source_id)
+          .SetWorkerType(blink::IdentifiableSurface::WorkerType::kServiceWorker)
+          .Record(ukm_recorder);
+    }
   }
 }
 
diff --git a/content/browser/worker_host/shared_worker_host.cc b/content/browser/worker_host/shared_worker_host.cc
index 30335d7..85dd8e4 100644
--- a/content/browser/worker_host/shared_worker_host.cc
+++ b/content/browser/worker_host/shared_worker_host.cc
@@ -47,6 +47,8 @@
 #include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/common/loader/url_loader_factory_bundle.h"
 #include "third_party/blink/public/common/messaging/message_port_channel.h"
+#include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h"
+#include "third_party/blink/public/common/privacy_budget/identifiability_study_worker_client_added.h"
 #include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h"
 #include "third_party/blink/public/mojom/renderer_preference_watcher.mojom.h"
 #include "third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom.h"
@@ -695,6 +697,13 @@
         .SetClientSourceId(client_ukm_source_id)
         .SetWorkerType(static_cast<int64_t>(WorkerType::kSharedWorker))
         .Record(ukm_recorder);
+
+    if (blink::IdentifiabilityStudySettings::Get()->IsActive()) {
+      blink::IdentifiabilityStudyWorkerClientAdded(ukm_source_id_)
+          .SetClientSourceId(client_ukm_source_id)
+          .SetWorkerType(blink::IdentifiableSurface::WorkerType::kSharedWorker)
+          .Record(ukm_recorder);
+    }
   }
 
   worker_->Connect(info.connection_request_id, port.ReleaseHandle());
diff --git a/content/public/browser/ax_inspect_factory_win.cc b/content/public/browser/ax_inspect_factory_win.cc
index 2aac3f0..54f13af4 100644
--- a/content/public/browser/ax_inspect_factory_win.cc
+++ b/content/public/browser/ax_inspect_factory_win.cc
@@ -8,11 +8,11 @@
 #include "base/notreached.h"
 #include "base/win/com_init_util.h"
 #include "content/browser/accessibility/accessibility_tree_formatter_blink.h"
-#include "content/browser/accessibility/accessibility_tree_formatter_win.h"
 #include "content/browser/accessibility/browser_accessibility_manager.h"
 #include "ui/accessibility/platform/inspect/ax_event_recorder_win.h"
 #include "ui/accessibility/platform/inspect/ax_event_recorder_win_uia.h"
 #include "ui/accessibility/platform/inspect/ax_tree_formatter_uia_win.h"
+#include "ui/accessibility/platform/inspect/ax_tree_formatter_win.h"
 
 namespace content {
 
@@ -44,7 +44,7 @@
       return std::make_unique<AccessibilityTreeFormatterBlink>();
     case ui::AXApiType::kWinIA2:
       base::win::AssertComInitialized();
-      return std::make_unique<AccessibilityTreeFormatterWin>();
+      return std::make_unique<ui::AXTreeFormatterWin>();
     case ui::AXApiType::kWinUIA:
       base::win::AssertComInitialized();
       return std::make_unique<ui::AXTreeFormatterUia>();
diff --git a/content/public/common/content_switch_dependent_feature_overrides.cc b/content/public/common/content_switch_dependent_feature_overrides.cc
index c635e33..cfdb8d1 100644
--- a/content/public/common/content_switch_dependent_feature_overrides.cc
+++ b/content/public/common/content_switch_dependent_feature_overrides.cc
@@ -67,6 +67,9 @@
      std::cref(features::kBlockInsecurePrivateNetworkRequestsFromUnknown),
      base::FeatureList::OVERRIDE_ENABLE_FEATURE},
     {switches::kEnableExperimentalWebPlatformFeatures,
+     std::cref(features::kBlockInsecurePrivateNetworkRequestsForNavigations),
+     base::FeatureList::OVERRIDE_ENABLE_FEATURE},
+    {switches::kEnableExperimentalWebPlatformFeatures,
      std::cref(features::kPrivateNetworkAccessForWorkers),
      base::FeatureList::OVERRIDE_ENABLE_FEATURE},
     {switches::kEnableExperimentalWebPlatformFeatures,
diff --git a/content/public/renderer/content_renderer_client.cc b/content/public/renderer/content_renderer_client.cc
index 76c44e9..52aec85 100644
--- a/content/public/renderer/content_renderer_client.cc
+++ b/content/public/renderer/content_renderer_client.cc
@@ -74,7 +74,7 @@
 std::unique_ptr<media::Demuxer> ContentRendererClient::OverrideDemuxerForUrl(
     RenderFrame* render_frame,
     const GURL& url,
-    scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
+    scoped_refptr<base::SequencedTaskRunner> task_runner) {
   return nullptr;
 }
 
diff --git a/content/public/renderer/content_renderer_client.h b/content/public/renderer/content_renderer_client.h
index 69e9da01..72e0eb7 100644
--- a/content/public/renderer/content_renderer_client.h
+++ b/content/public/renderer/content_renderer_client.h
@@ -15,6 +15,7 @@
 #include "base/callback_forward.h"
 #include "base/files/file_path.h"
 #include "base/memory/ref_counted.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/task/thread_pool/thread_pool_instance.h"
 #include "build/build_config.h"
 #include "content/common/content_export.h"
@@ -180,7 +181,7 @@
   virtual std::unique_ptr<media::Demuxer> OverrideDemuxerForUrl(
       RenderFrame* render_frame,
       const GURL& url,
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+      scoped_refptr<base::SequencedTaskRunner> task_runner);
 
   // Allows the embedder to provide a WebSocketHandshakeThrottleProvider. If it
   // returns NULL then none will be used.
diff --git a/content/public/test/back_forward_cache_util.cc b/content/public/test/back_forward_cache_util.cc
index 82a2527..37a3ee0 100644
--- a/content/public/test/back_forward_cache_util.cc
+++ b/content/public/test/back_forward_cache_util.cc
@@ -9,13 +9,12 @@
 
 #include "base/containers/contains.h"
 #include "base/ranges/algorithm.h"
+#include "base/test/scoped_feature_list.h"
 #include "content/browser/renderer_host/back_forward_cache_impl.h"
 #include "content/public/browser/global_routing_id.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/content_features.h"
 
-using base::test::ScopedFeatureList;
-
 namespace content {
 
 class BackForwardCacheDisabledTester::Impl
@@ -57,29 +56,29 @@
   web_contents->GetController().GetBackForwardCache().DisableForTesting(reason);
 }
 
-std::vector<ScopedFeatureList::FeatureAndParams>
+std::vector<base::test::FeatureRefAndParams>
 DefaultEnabledBackForwardCacheParametersForTests() {
   return DefaultEnabledBackForwardCacheParametersForTests({});
 }
 
-std::vector<ScopedFeatureList::FeatureAndParams>
+std::vector<base::test::FeatureRefAndParams>
 DefaultEnabledBackForwardCacheParametersForTests(
-    const std::vector<ScopedFeatureList::FeatureAndParams>& additional_params) {
+    const std::vector<base::test::FeatureRefAndParams>& additional_params) {
   // TODO(https://crbug.com/1301867): Remove the default parameters from the
   // kBackForwardCache feature and remove the complex parameter merging code.
-  std::vector<ScopedFeatureList::FeatureAndParams> default_features_and_params =
-      {{features::kBackForwardCache,
-        {{"ignore_outstanding_network_request_for_testing", "true"}}},
-       {kBackForwardCacheTimeToLiveControl,
-        {{"time_to_live_in_seconds", "3600"}}}};
-  std::vector<ScopedFeatureList::FeatureAndParams> final_params;
+  std::vector<base::test::FeatureRefAndParams> default_features_and_params = {
+      {features::kBackForwardCache,
+       {{"ignore_outstanding_network_request_for_testing", "true"}}},
+      {kBackForwardCacheTimeToLiveControl,
+       {{"time_to_live_in_seconds", "3600"}}}};
+  std::vector<base::test::FeatureRefAndParams> final_params;
   // Go over the additional features/params - if they match a default feature,
   // make a new featureparam with the combined features, otherwise just add the
   // additional feature as is.
   for (auto feature_and_params : additional_params) {
     auto default_feature_and_param = base::ranges::find(
         default_features_and_params, feature_and_params.feature.name,
-        [](const ScopedFeatureList::FeatureAndParams default_feature) {
+        [](const base::test::FeatureRefAndParams default_feature) {
           return default_feature.feature.name;
         });
     if (default_feature_and_param != default_features_and_params.end()) {
@@ -88,7 +87,7 @@
                              default_feature_and_param->params.end());
       combined_params.insert(feature_and_params.params.begin(),
                              feature_and_params.params.end());
-      final_params.emplace_back(ScopedFeatureList::FeatureAndParams(
+      final_params.emplace_back(base::test::FeatureRefAndParams(
           feature_and_params.feature, combined_params));
     } else {
       final_params.emplace_back(feature_and_params);
@@ -98,7 +97,7 @@
   for (auto feature_and_params : default_features_and_params) {
     if (!base::Contains(
             final_params, feature_and_params.feature.name,
-            [](const ScopedFeatureList::FeatureAndParams default_feature) {
+            [](const base::test::FeatureRefAndParams default_feature) {
               return default_feature.feature.name;
             })) {
       final_params.emplace_back(feature_and_params);
diff --git a/content/public/test/prerender_test_util.cc b/content/public/test/prerender_test_util.cc
index d0c4f3c9..fd86192 100644
--- a/content/public/test/prerender_test_util.cc
+++ b/content/public/test/prerender_test_util.cc
@@ -230,21 +230,10 @@
 }
 
 ScopedPrerenderFeatureList::ScopedPrerenderFeatureList() {
-  std::vector<base::test::FeatureRef> enabled_features;
-#if !BUILDFLAG(IS_ANDROID)
-  // Prerender2 for Speculation Rules should be enabled by default on Android.
-  // To test the default behavior on Android, explicitly enable the feature only
-  // on non-Android.
-  //
-  // This is useful for preventing breakages by future changes on the complex
-  // flag structure. See review comments on https://crrev.com/c/3670822 for
-  // details.
-  enabled_features.push_back(blink::features::kPrerender2);
-#endif
-  feature_list_.InitWithFeatures(enabled_features,
-                                 // Disable the memory requirement of Prerender2
-                                 // so the test can run on any bot.
-                                 {blink::features::kPrerender2MemoryControls});
+  // Disable the memory requirement of Prerender2
+  // so the test can run on any bot.
+  feature_list_.InitAndDisableFeature(
+      blink::features::kPrerender2MemoryControls);
 }
 
 PrerenderTestHelper::PrerenderTestHelper(const WebContents::Getter& fn)
diff --git a/content/renderer/media/android/flinging_renderer_client.cc b/content/renderer/media/android/flinging_renderer_client.cc
index 75db1c5b..b82184f 100644
--- a/content/renderer/media/android/flinging_renderer_client.cc
+++ b/content/renderer/media/android/flinging_renderer_client.cc
@@ -13,7 +13,7 @@
 
 FlingingRendererClient::FlingingRendererClient(
     ClientExtentionPendingReceiver client_extension_receiver,
-    scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+    scoped_refptr<base::SequencedTaskRunner> media_task_runner,
     std::unique_ptr<media::MojoRenderer> mojo_renderer,
     media::RemotePlayStateChangeCB remote_play_state_change_cb)
     : MojoRendererWrapper(std::move(mojo_renderer)),
@@ -27,7 +27,7 @@
 void FlingingRendererClient::Initialize(media::MediaResource* media_resource,
                                         media::RendererClient* client,
                                         media::PipelineStatusCallback init_cb) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   client_ = client;
 
@@ -39,7 +39,7 @@
 
 void FlingingRendererClient::OnRemotePlayStateChange(
     media::MediaStatus::State state) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   remote_play_state_change_cb_.Run(state);
 }
 
diff --git a/content/renderer/media/android/flinging_renderer_client.h b/content/renderer/media/android/flinging_renderer_client.h
index e304f60d..3ce4f2b 100644
--- a/content/renderer/media/android/flinging_renderer_client.h
+++ b/content/renderer/media/android/flinging_renderer_client.h
@@ -9,6 +9,7 @@
 
 #include "base/callback.h"
 #include "base/memory/weak_ptr.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/task/single_thread_task_runner.h"
 #include "content/common/content_export.h"
 #include "media/base/media_resource.h"
@@ -34,7 +35,7 @@
 
   FlingingRendererClient(
       ClientExtentionPendingReceiver client_extension_receiver,
-      scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+      scoped_refptr<base::SequencedTaskRunner> media_task_runner,
       std::unique_ptr<media::MojoRenderer> mojo_renderer,
       media::RemotePlayStateChangeCB remote_play_state_change_cb);
 
@@ -52,7 +53,7 @@
   void OnRemotePlayStateChange(media::MediaStatus::State state) override;
 
  private:
-  scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+  scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
 
   media::RendererClient* client_;
 
diff --git a/content/renderer/media/android/flinging_renderer_client_factory.cc b/content/renderer/media/android/flinging_renderer_client_factory.cc
index 57341ab..6298f1b 100644
--- a/content/renderer/media/android/flinging_renderer_client_factory.cc
+++ b/content/renderer/media/android/flinging_renderer_client_factory.cc
@@ -26,7 +26,7 @@
 FlingingRendererClientFactory::~FlingingRendererClientFactory() = default;
 
 std::unique_ptr<media::Renderer> FlingingRendererClientFactory::CreateRenderer(
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
     const scoped_refptr<base::TaskRunner>& worker_task_runner,
     media::AudioRendererSink* audio_renderer_sink,
     media::VideoRendererSink* video_renderer_sink,
diff --git a/content/renderer/media/android/flinging_renderer_client_factory.h b/content/renderer/media/android/flinging_renderer_client_factory.h
index 596dc0d8..aead4dc 100644
--- a/content/renderer/media/android/flinging_renderer_client_factory.h
+++ b/content/renderer/media/android/flinging_renderer_client_factory.h
@@ -42,7 +42,7 @@
   void SetRemotePlayStateChangeCB(media::RemotePlayStateChangeCB callback);
 
   std::unique_ptr<media::Renderer> CreateRenderer(
-      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+      const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
       const scoped_refptr<base::TaskRunner>& worker_task_runner,
       media::AudioRendererSink* audio_renderer_sink,
       media::VideoRendererSink* video_renderer_sink,
diff --git a/content/renderer/media/android/media_player_renderer_client.cc b/content/renderer/media/android/media_player_renderer_client.cc
index 7ef2f6b..6b84a40 100644
--- a/content/renderer/media/android/media_player_renderer_client.cc
+++ b/content/renderer/media/android/media_player_renderer_client.cc
@@ -13,7 +13,7 @@
 MediaPlayerRendererClient::MediaPlayerRendererClient(
     mojo::PendingRemote<RendererExtention> renderer_extension_remote,
     mojo::PendingReceiver<ClientExtention> client_extension_receiver,
-    scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+    scoped_refptr<base::SequencedTaskRunner> media_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
     std::unique_ptr<media::MojoRenderer> mojo_renderer,
     media::ScopedStreamTextureWrapper stream_texture_wrapper,
@@ -41,7 +41,7 @@
     media::MediaResource* media_resource,
     media::RendererClient* client,
     media::PipelineStatusCallback init_cb) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(!init_cb_);
 
   // Consume and bind the delayed PendingRemote and PendingReceiver now that we
@@ -70,7 +70,7 @@
 void MediaPlayerRendererClient::OnStreamTextureWrapperInitialized(
     media::MediaResource* media_resource,
     bool success) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   if (!success) {
     std::move(init_cb_).Run(
         media::PipelineStatus::Codes::PIPELINE_ERROR_INITIALIZATION_FAILED);
@@ -95,7 +95,7 @@
 
 void MediaPlayerRendererClient::OnRemoteRendererInitialized(
     media::PipelineStatus status) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(!init_cb_.is_null());
 
   if (status == media::PIPELINE_OK) {
@@ -136,7 +136,7 @@
 }
 
 void MediaPlayerRendererClient::OnDurationChange(base::TimeDelta duration) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   media_resource_->ForwardDurationChangeToDemuxerHost(duration);
 }
diff --git a/content/renderer/media/android/media_player_renderer_client.h b/content/renderer/media/android/media_player_renderer_client.h
index 5a3d9622..8d91c0e 100644
--- a/content/renderer/media/android/media_player_renderer_client.h
+++ b/content/renderer/media/android/media_player_renderer_client.h
@@ -46,7 +46,7 @@
   MediaPlayerRendererClient(
       mojo::PendingRemote<RendererExtention> renderer_extension_remote,
       mojo::PendingReceiver<ClientExtention> client_extension_receiver,
-      scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+      scoped_refptr<base::SequencedTaskRunner> media_task_runner,
       scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
       std::unique_ptr<media::MojoRenderer> mojo_renderer,
       media::ScopedStreamTextureWrapper stream_texture_wrapper,
@@ -92,8 +92,7 @@
 
   media::VideoRendererSink* sink_;
 
-  scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
-
+  scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
   // Used by |stream_texture_wrapper_| to signal OnFrameAvailable() and to send
   // VideoFrames to |sink_| on the right thread.
   scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
diff --git a/content/renderer/media/android/media_player_renderer_client_factory.cc b/content/renderer/media/android/media_player_renderer_client_factory.cc
index 09447ba..898c4c0 100644
--- a/content/renderer/media/android/media_player_renderer_client_factory.cc
+++ b/content/renderer/media/android/media_player_renderer_client_factory.cc
@@ -23,7 +23,7 @@
 
 std::unique_ptr<media::Renderer>
 MediaPlayerRendererClientFactory::CreateRenderer(
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
     const scoped_refptr<base::TaskRunner>& worker_task_runner,
     media::AudioRendererSink* audio_renderer_sink,
     media::VideoRendererSink* video_renderer_sink,
diff --git a/content/renderer/media/android/media_player_renderer_client_factory.h b/content/renderer/media/android/media_player_renderer_client_factory.h
index 7d6bb556..0f1b1c7 100644
--- a/content/renderer/media/android/media_player_renderer_client_factory.h
+++ b/content/renderer/media/android/media_player_renderer_client_factory.h
@@ -35,7 +35,7 @@
   ~MediaPlayerRendererClientFactory() override;
 
   std::unique_ptr<media::Renderer> CreateRenderer(
-      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+      const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
       const scoped_refptr<base::TaskRunner>& worker_task_runner,
       media::AudioRendererSink* audio_renderer_sink,
       media::VideoRendererSink* video_renderer_sink,
diff --git a/content/renderer/media/cast_renderer_client_factory.cc b/content/renderer/media/cast_renderer_client_factory.cc
index a13f879c..9678eee9 100644
--- a/content/renderer/media/cast_renderer_client_factory.cc
+++ b/content/renderer/media/cast_renderer_client_factory.cc
@@ -19,7 +19,7 @@
 CastRendererClientFactory::~CastRendererClientFactory() = default;
 
 std::unique_ptr<media::Renderer> CastRendererClientFactory::CreateRenderer(
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
     const scoped_refptr<base::TaskRunner>& worker_task_runner,
     media::AudioRendererSink* audio_renderer_sink,
     media::VideoRendererSink* video_renderer_sink,
diff --git a/content/renderer/media/cast_renderer_client_factory.h b/content/renderer/media/cast_renderer_client_factory.h
index 5ce0902..70f19f5 100644
--- a/content/renderer/media/cast_renderer_client_factory.h
+++ b/content/renderer/media/cast_renderer_client_factory.h
@@ -36,7 +36,7 @@
   ~CastRendererClientFactory() override;
 
   std::unique_ptr<media::Renderer> CreateRenderer(
-      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+      const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
       const scoped_refptr<base::TaskRunner>& worker_task_runner,
       media::AudioRendererSink* audio_renderer_sink,
       media::VideoRendererSink* video_renderer_sink,
diff --git a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc
index 112586f..55ec6275 100644
--- a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc
+++ b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc
@@ -146,7 +146,7 @@
   interface_factory_.Bind(std::move(interface_factory_remote));
   vea_provider_.Bind(std::move(vea_provider_remote));
 
-  if (context_provider_->BindToCurrentThread() !=
+  if (context_provider_->BindToCurrentSequence() !=
       gpu::ContextResult::kSuccess) {
     OnDecoderSupportFailed();
     OnEncoderSupportFailed();
diff --git a/content/renderer/media/media_factory.cc b/content/renderer/media/media_factory.cc
index fc6f9b8..9c21a263 100644
--- a/content/renderer/media/media_factory.cc
+++ b/content/renderer/media/media_factory.cc
@@ -15,6 +15,7 @@
 #include "base/metrics/field_trial_params.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
 #include "build/buildflag.h"
@@ -332,7 +333,7 @@
     // this time and subsequently a media thread. To fail, the media thread must
     // be dead/dying (which only happens at ~RenderThreadImpl), in which case
     // the process is about to die anyways.
-    RenderThreadImpl::current()->GetMediaThreadTaskRunner()->DeleteSoon(
+    RenderThreadImpl::current()->GetMediaSequencedTaskRunner()->DeleteSoon(
         FROM_HERE, std::move(decoder_factory_));
   }
 }
@@ -474,8 +475,8 @@
                             media_log.get(), render_frame_)
           : nullptr;
 
-  scoped_refptr<base::SingleThreadTaskRunner> media_task_runner =
-      render_thread->GetMediaThreadTaskRunner();
+  scoped_refptr<base::SequencedTaskRunner> media_task_runner =
+      render_thread->GetMediaSequencedTaskRunner();
 
   if (!media_task_runner) {
     // If the media thread failed to start, we will receive a null task runner.
@@ -680,7 +681,7 @@
     auto dcomp_texture_creation_cb =
         base::BindRepeating(&DCOMPTextureWrapperImpl::Create,
                             render_thread->GetDCOMPTextureFactory(),
-                            render_thread->GetMediaThreadTaskRunner());
+                            render_thread->GetMediaSequencedTaskRunner());
 
     mojo::Remote<media::mojom::MediaFoundationRendererNotifier>
         media_foundation_renderer_notifier;
@@ -726,7 +727,7 @@
     auto remoting_renderer_factory =
         std::make_unique<media::remoting::RemotingRendererFactory>(
             std::move(remotee), std::move(default_factory_remoting),
-            render_thread->GetMediaThreadTaskRunner());
+            render_thread->GetMediaSequencedTaskRunner());
     auto is_remoting_media = base::BindRepeating(
         [](const GURL& url) -> bool {
           return url.SchemeIs(media::remoting::kRemotingScheme);
@@ -788,7 +789,7 @@
       render_frame_->GetTaskRunner(blink::TaskType::kInternalMedia),
       render_thread->GetIOTaskRunner(),
       GetOrCreateVideoFrameCompositorTaskRunner(render_frame_),
-      render_thread->GetMediaThreadTaskRunner(),
+      render_thread->GetMediaSequencedTaskRunner(),
       std::move(compositor_worker_task_runner),
       render_thread->GetGpuFactories(), sink_id,
       base::BindOnce(&blink::WebSurfaceLayerBridge::Create,
diff --git a/content/renderer/media/win/dcomp_texture_factory.cc b/content/renderer/media/win/dcomp_texture_factory.cc
index f43b5b5b..5b9f0ae 100644
--- a/content/renderer/media/win/dcomp_texture_factory.cc
+++ b/content/renderer/media/win/dcomp_texture_factory.cc
@@ -15,7 +15,7 @@
 // static
 scoped_refptr<DCOMPTextureFactory> DCOMPTextureFactory::Create(
     scoped_refptr<gpu::GpuChannelHost> channel,
-    scoped_refptr<base::SingleThreadTaskRunner> media_task_runner) {
+    scoped_refptr<base::SequencedTaskRunner> media_task_runner) {
   DVLOG(1) << __func__;
   return WrapRefCounted(
       new DCOMPTextureFactory(std::move(channel), media_task_runner));
@@ -23,7 +23,7 @@
 
 DCOMPTextureFactory::DCOMPTextureFactory(
     scoped_refptr<gpu::GpuChannelHost> channel,
-    scoped_refptr<base::SingleThreadTaskRunner> media_task_runner)
+    scoped_refptr<base::SequencedTaskRunner> media_task_runner)
     : channel_(std::move(channel)), media_task_runner_(media_task_runner) {
   DVLOG_FUNC(1);
   DCHECK(channel_);
@@ -34,7 +34,7 @@
 std::unique_ptr<DCOMPTextureHost> DCOMPTextureFactory::CreateDCOMPTextureHost(
     DCOMPTextureHost::Listener* listener) {
   DVLOG_FUNC(1);
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   int32_t route_id = channel_->GenerateRouteID();
   mojo::PendingAssociatedRemote<gpu::mojom::DCOMPTexture> remote;
@@ -58,7 +58,7 @@
 }
 
 gpu::SharedImageInterface* DCOMPTextureFactory::SharedImageInterface() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   if (!shared_image_interface_)
     shared_image_interface_ = channel_->CreateClientSharedImageInterface();
diff --git a/content/renderer/media/win/dcomp_texture_factory.h b/content/renderer/media/win/dcomp_texture_factory.h
index b1f33b4..5f5945c 100644
--- a/content/renderer/media/win/dcomp_texture_factory.h
+++ b/content/renderer/media/win/dcomp_texture_factory.h
@@ -10,7 +10,7 @@
 #include <memory>
 
 #include "base/memory/ref_counted.h"
-#include "base/task/single_thread_task_runner.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/unguessable_token.h"
 #include "cc/layers/video_frame_provider.h"
 #include "content/common/content_export.h"
@@ -39,7 +39,7 @@
  public:
   static scoped_refptr<DCOMPTextureFactory> Create(
       scoped_refptr<gpu::GpuChannelHost> channel,
-      scoped_refptr<base::SingleThreadTaskRunner> media_task_runner);
+      scoped_refptr<base::SequencedTaskRunner> media_task_runner);
 
   // Create the DCOMPTextureHost object. This internally creates a
   // gpu::DCOMPTexture and returns its route_id. If this route_id is invalid
@@ -56,7 +56,7 @@
  protected:
   DCOMPTextureFactory(
       scoped_refptr<gpu::GpuChannelHost> channel,
-      scoped_refptr<base::SingleThreadTaskRunner> media_task_runner);
+      scoped_refptr<base::SequencedTaskRunner> media_task_runner);
   DCOMPTextureFactory(const DCOMPTextureFactory&) = delete;
   DCOMPTextureFactory& operator=(const DCOMPTextureFactory&) = delete;
   virtual ~DCOMPTextureFactory();
@@ -65,7 +65,7 @@
   friend class base::RefCountedThreadSafe<DCOMPTextureFactory>;
 
   scoped_refptr<gpu::GpuChannelHost> channel_;
-  scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+  scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
   std::unique_ptr<gpu::ClientSharedImageInterface> shared_image_interface_;
 };
 
diff --git a/content/renderer/media/win/dcomp_texture_host.cc b/content/renderer/media/win/dcomp_texture_host.cc
index cc88e83..46c85e4 100644
--- a/content/renderer/media/win/dcomp_texture_host.cc
+++ b/content/renderer/media/win/dcomp_texture_host.cc
@@ -18,12 +18,12 @@
 DCOMPTextureHost::DCOMPTextureHost(
     scoped_refptr<gpu::GpuChannelHost> channel,
     int32_t route_id,
-    scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+    scoped_refptr<base::SequencedTaskRunner> media_task_runner,
     mojo::PendingAssociatedRemote<gpu::mojom::DCOMPTexture> texture,
     Listener* listener)
     : channel_(std::move(channel)), route_id_(route_id), listener_(listener) {
   DVLOG_FUNC(1);
-  DCHECK(media_task_runner->BelongsToCurrentThread());
+  DCHECK(media_task_runner->RunsTasksInCurrentSequence());
   DCHECK(channel_);
   DCHECK(route_id_);
   DCHECK(listener_);
diff --git a/content/renderer/media/win/dcomp_texture_host.h b/content/renderer/media/win/dcomp_texture_host.h
index 7ab566f0..7db6626 100644
--- a/content/renderer/media/win/dcomp_texture_host.h
+++ b/content/renderer/media/win/dcomp_texture_host.h
@@ -7,6 +7,7 @@
 
 #include <stdint.h>
 
+#include "base/task/sequenced_task_runner.h"
 #include "base/unguessable_token.h"
 #include "base/win/windows_types.h"
 #include "gpu/ipc/common/gpu_channel.mojom.h"
@@ -42,7 +43,7 @@
   DCOMPTextureHost(
       scoped_refptr<gpu::GpuChannelHost> channel,
       int32_t route_id,
-      scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+      scoped_refptr<base::SequencedTaskRunner> media_task_runner,
       mojo::PendingAssociatedRemote<gpu::mojom::DCOMPTexture> texture,
       Listener* listener);
   DCOMPTextureHost(const DCOMPTextureHost&) = delete;
diff --git a/content/renderer/media/win/dcomp_texture_wrapper_impl.cc b/content/renderer/media/win/dcomp_texture_wrapper_impl.cc
index f7e5d63..23c67ff2 100644
--- a/content/renderer/media/win/dcomp_texture_wrapper_impl.cc
+++ b/content/renderer/media/win/dcomp_texture_wrapper_impl.cc
@@ -78,7 +78,7 @@
 // static
 std::unique_ptr<media::DCOMPTextureWrapper> DCOMPTextureWrapperImpl::Create(
     scoped_refptr<DCOMPTextureFactory> factory,
-    scoped_refptr<base::SingleThreadTaskRunner> media_task_runner) {
+    scoped_refptr<base::SequencedTaskRunner> media_task_runner) {
   DVLOG(1) << __func__;
   // auto* impl = new DCOMPTextureWrapperImpl(factory, media_task_runner);
   return base::WrapUnique(
@@ -87,14 +87,14 @@
 
 DCOMPTextureWrapperImpl::DCOMPTextureWrapperImpl(
     scoped_refptr<DCOMPTextureFactory> factory,
-    scoped_refptr<base::SingleThreadTaskRunner> media_task_runner)
+    scoped_refptr<base::SequencedTaskRunner> media_task_runner)
     : factory_(factory), media_task_runner_(media_task_runner) {
   DVLOG_FUNC(1);
 }
 
 DCOMPTextureWrapperImpl::~DCOMPTextureWrapperImpl() {
   DVLOG_FUNC(1);
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   // We do not need any additional cleanup logic here as the
   // OnReleaseVideoFrame() callback handles cleaning up the shared image.
@@ -104,7 +104,7 @@
     const gfx::Size& output_size,
     OutputRectChangeCB output_rect_change_cb) {
   DVLOG_FUNC(1);
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   output_size_ = output_size;
 
@@ -118,7 +118,7 @@
 
 void DCOMPTextureWrapperImpl::UpdateTextureSize(const gfx::Size& new_size) {
   DVLOG_FUNC(2);
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   // We would like to invoke SetTextureSize() which will let DCOMPTexture to
   // bind a mailbox to its SharedImage as early as possible. Let new_size of
@@ -134,7 +134,7 @@
     const base::UnguessableToken& token,
     SetDCOMPSurfaceHandleCB set_dcomp_surface_handle_cb) {
   DVLOG_FUNC(1);
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   dcomp_texture_host_->SetDCOMPSurfaceHandle(
       token, std::move(set_dcomp_surface_handle_cb));
@@ -144,7 +144,7 @@
     const gfx::Size& natural_size,
     CreateVideoFrameCB create_video_frame_cb) {
   DVLOG_FUNC(2);
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   natural_size_ = natural_size;
   if (mailbox_.IsZero()) {
@@ -190,7 +190,7 @@
     const gfx::Size& natural_size,
     gfx::GpuMemoryBufferHandle dx_handle,
     CreateDXVideoFrameCB create_video_frame_cb) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   gpu::SharedImageInterface* sii = factory_->SharedImageInterface();
 
   uint32_t usage = gpu::SHARED_IMAGE_USAGE_RASTER |
@@ -234,14 +234,14 @@
 void DCOMPTextureWrapperImpl::OnDXVideoFrameDestruction(
     const gpu::SyncToken& sync_token,
     const gpu::Mailbox& image_mailbox) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   gpu::SharedImageInterface* sii = factory_->SharedImageInterface();
   sii->DestroySharedImage(sync_token, image_mailbox);
 }
 
 void DCOMPTextureWrapperImpl::OnSharedImageMailboxBound(gpu::Mailbox mailbox) {
   DVLOG_FUNC(1);
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   mailbox_ = std::move(mailbox);
 
@@ -253,7 +253,7 @@
 
 void DCOMPTextureWrapperImpl::OnOutputRectChange(gfx::Rect output_rect) {
   DVLOG_FUNC(1);
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   output_rect_change_cb_.Run(output_rect);
 }
diff --git a/content/renderer/media/win/dcomp_texture_wrapper_impl.h b/content/renderer/media/win/dcomp_texture_wrapper_impl.h
index 60d6a32..60e89d7 100644
--- a/content/renderer/media/win/dcomp_texture_wrapper_impl.h
+++ b/content/renderer/media/win/dcomp_texture_wrapper_impl.h
@@ -5,7 +5,7 @@
 #ifndef CONTENT_RENDERER_MEDIA_WIN_DCOMP_TEXTURE_WRAPPER_IMPL_H_
 #define CONTENT_RENDERER_MEDIA_WIN_DCOMP_TEXTURE_WRAPPER_IMPL_H_
 
-#include "base/task/single_thread_task_runner.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/unguessable_token.h"
 #include "content/common/content_export.h"
 #include "content/renderer/media/win/dcomp_texture_factory.h"
@@ -38,7 +38,7 @@
  public:
   static std::unique_ptr<media::DCOMPTextureWrapper> Create(
       scoped_refptr<DCOMPTextureFactory> factory,
-      scoped_refptr<base::SingleThreadTaskRunner> media_task_runner);
+      scoped_refptr<base::SequencedTaskRunner> media_task_runner);
 
   ~DCOMPTextureWrapperImpl() override;
 
@@ -61,7 +61,7 @@
  private:
   DCOMPTextureWrapperImpl(
       scoped_refptr<DCOMPTextureFactory> factory,
-      scoped_refptr<base::SingleThreadTaskRunner> media_task_runner);
+      scoped_refptr<base::SequencedTaskRunner> media_task_runner);
   DCOMPTextureWrapperImpl(const DCOMPTextureWrapperImpl&) = delete;
   DCOMPTextureWrapperImpl& operator=(const DCOMPTextureWrapperImpl&) = delete;
 
@@ -73,7 +73,7 @@
                                  const gpu::Mailbox& image_mailbox);
 
   scoped_refptr<DCOMPTextureFactory> factory_;
-  scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+  scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
 
   gfx::Size natural_size_;  // Size of the video frames.
   gfx::Size output_size_;   // Size of the video output (on-screen size).
diff --git a/content/renderer/pepper/video_decoder_shim.cc b/content/renderer/pepper/video_decoder_shim.cc
index 09449e1..252b52c42 100644
--- a/content/renderer/pepper/video_decoder_shim.cc
+++ b/content/renderer/pepper/video_decoder_shim.cc
@@ -305,7 +305,7 @@
     : state_(UNINITIALIZED),
       host_(host),
       media_task_runner_(
-          RenderThreadImpl::current()->GetMediaThreadTaskRunner()),
+          RenderThreadImpl::current()->GetMediaSequencedTaskRunner()),
       context_provider_(
           RenderThreadImpl::current()->SharedMainThreadContextProvider()),
       texture_pool_size_(texture_pool_size),
diff --git a/content/renderer/pepper/video_decoder_shim.h b/content/renderer/pepper/video_decoder_shim.h
index 278d47a..7640b3e 100644
--- a/content/renderer/pepper/video_decoder_shim.h
+++ b/content/renderer/pepper/video_decoder_shim.h
@@ -14,14 +14,11 @@
 
 #include "base/containers/queue.h"
 #include "base/memory/weak_ptr.h"
+#include "base/task/sequenced_task_runner.h"
 #include "media/base/video_decoder_config.h"
 #include "media/video/video_decode_accelerator.h"
 #include "ppapi/c/pp_codecs.h"
 
-namespace base {
-class SingleThreadTaskRunner;
-}
-
 namespace viz {
 class ContextProviderCommandBuffer;
 }
@@ -81,7 +78,7 @@
   State state_;
 
   PepperVideoDecoderHost* host_;
-  scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+  scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
   scoped_refptr<viz::ContextProviderCommandBuffer> context_provider_;
 
   // The current decoded frame size.
diff --git a/content/renderer/pepper/video_encoder_shim.cc b/content/renderer/pepper/video_encoder_shim.cc
index 32dd49ae..16faa6f 100644
--- a/content/renderer/pepper/video_encoder_shim.cc
+++ b/content/renderer/pepper/video_encoder_shim.cc
@@ -363,7 +363,7 @@
 VideoEncoderShim::VideoEncoderShim(PepperVideoEncoderHost* host)
     : host_(host),
       media_task_runner_(
-          RenderThreadImpl::current()->GetMediaThreadTaskRunner()) {
+          RenderThreadImpl::current()->GetMediaSequencedTaskRunner()) {
   encoder_impl_ = std::make_unique<EncoderImpl>(weak_ptr_factory_.GetWeakPtr());
 }
 
diff --git a/content/renderer/pepper/video_encoder_shim.h b/content/renderer/pepper/video_encoder_shim.h
index 9c2eebf..26ff364 100644
--- a/content/renderer/pepper/video_encoder_shim.h
+++ b/content/renderer/pepper/video_encoder_shim.h
@@ -12,13 +12,10 @@
 #include <vector>
 
 #include "base/memory/weak_ptr.h"
+#include "base/task/sequenced_task_runner.h"
 #include "media/base/bitrate.h"
 #include "media/video/video_encode_accelerator.h"
 
-namespace base {
-class SingleThreadTaskRunner;
-}
-
 namespace gfx {
 class Size;
 }
@@ -71,7 +68,7 @@
   PepperVideoEncoderHost* host_;
 
   // Task doing the encoding.
-  scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+  scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
 
   base::WeakPtrFactory<VideoEncoderShim> weak_ptr_factory_{this};
 };
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 17b6280..247e70d 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -993,7 +993,7 @@
     if (!gpu_factories_.back()->CheckContextProviderLostOnMainThread())
       return gpu_factories_.back().get();
 
-    GetMediaThreadTaskRunner()->PostTask(
+    GetMediaSequencedTaskRunner()->PostTask(
         FROM_HERE,
         base::BindOnce(&GpuVideoAcceleratorFactoriesImpl::DestroyContext,
                        base::Unretained(gpu_factories_.back().get())));
@@ -1078,7 +1078,7 @@
 
   gpu_factories_.push_back(GpuVideoAcceleratorFactoriesImpl::Create(
       std::move(gpu_channel_host), base::ThreadTaskRunnerHandle::Get(),
-      GetMediaThreadTaskRunner(), std::move(media_context_provider),
+      GetMediaSequencedTaskRunner(), std::move(media_context_provider),
       enable_video_gpu_memory_buffers, enable_media_stream_gpu_memory_buffers,
       enable_video_decode_accelerator, enable_video_encode_accelerator,
       std::move(interface_factory), std::move(vea_provider)));
@@ -1158,7 +1158,7 @@
       automatic_flushes,
       viz::command_buffer_metrics::ContextType::RENDERER_MAIN_THREAD,
       kGpuStreamIdDefault, kGpuStreamPriorityDefault);
-  auto result = shared_main_thread_contexts_->BindToCurrentThread();
+  auto result = shared_main_thread_contexts_->BindToCurrentSequence();
   if (result != gpu::ContextResult::kSuccess)
     shared_main_thread_contexts_ = nullptr;
   return shared_main_thread_contexts_;
@@ -1193,7 +1193,7 @@
       return nullptr;
     }
     dcomp_texture_factory_ = DCOMPTextureFactory::Create(
-        std::move(channel), GetMediaThreadTaskRunner());
+        std::move(channel), GetMediaSequencedTaskRunner());
   }
   return dcomp_texture_factory_;
 }
@@ -1582,8 +1582,8 @@
   }
 }
 
-scoped_refptr<base::SingleThreadTaskRunner>
-RenderThreadImpl::GetMediaThreadTaskRunner() {
+scoped_refptr<base::SequencedTaskRunner>
+RenderThreadImpl::GetMediaSequencedTaskRunner() {
   DCHECK(main_thread_runner()->BelongsToCurrentThread());
   if (!media_thread_) {
     media_thread_ = std::make_unique<base::Thread>("Media");
@@ -1640,7 +1640,7 @@
           viz::command_buffer_metrics::ContextType::RENDER_WORKER,
           kGpuStreamIdWorker, kGpuStreamPriorityWorker);
 
-  auto result = shared_worker_context_provider->BindToCurrentThread();
+  auto result = shared_worker_context_provider->BindToCurrentSequence();
   if (result != gpu::ContextResult::kSuccess)
     return nullptr;
 
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h
index b2fb8e3..f0474c1 100644
--- a/content/renderer/render_thread_impl.h
+++ b/content/renderer/render_thread_impl.h
@@ -24,6 +24,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/metrics/user_metrics_action.h"
 #include "base/observer_list.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/time/time.h"
 #include "base/types/pass_key.h"
 #include "build/build_config.h"
@@ -282,10 +283,9 @@
   // has been lost.
   gpu::GpuChannelHost* GetGpuChannel();
 
-  // Returns a SingleThreadTaskRunner instance corresponding to the message loop
-  // of the thread on which media operations should be run. Must be called
-  // on the renderer's main thread.
-  scoped_refptr<base::SingleThreadTaskRunner> GetMediaThreadTaskRunner();
+  // Returns the sequence on which media operations should be run. Must be
+  // called on the renderer's main thread.
+  scoped_refptr<base::SequencedTaskRunner> GetMediaSequencedTaskRunner();
 
   // Creates a ContextProvider if yet created, and returns it to be used for
   // video frame compositing. The ContextProvider given as an argument is
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
index 4cedfbfa..ebf53c6a 100644
--- a/content/renderer/renderer_blink_platform_impl.cc
+++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -25,6 +25,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/synchronization/lock.h"
 #include "base/synchronization/waitable_event.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/task/thread_pool.h"
 #include "base/threading/thread_restrictions.h"
@@ -972,13 +973,13 @@
   return render_thread->GetGpuFactories();
 }
 
-scoped_refptr<base::SingleThreadTaskRunner>
+scoped_refptr<base::SequencedTaskRunner>
 RendererBlinkPlatformImpl::MediaThreadTaskRunner() {
   auto* render_thread = RenderThreadImpl::current();
   if (!render_thread)
     return nullptr;
 
-  return render_thread->GetMediaThreadTaskRunner();
+  return render_thread->GetMediaSequencedTaskRunner();
 }
 
 base::WeakPtr<media::DecoderFactory>
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h
index 78ffa14..ff010df 100644
--- a/content/renderer/renderer_blink_platform_impl.h
+++ b/content/renderer/renderer_blink_platform_impl.h
@@ -14,6 +14,7 @@
 #include "base/containers/id_map.h"
 #include "base/synchronization/lock.h"
 #include "base/synchronization/waitable_event.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/thread_annotations.h"
 #include "base/threading/thread_checker.h"
@@ -213,7 +214,7 @@
       scoped_refptr<base::SingleThreadTaskRunner> owner_task_runner,
       bool is_on_worker) override;
   media::GpuVideoAcceleratorFactories* GetGpuFactories() override;
-  scoped_refptr<base::SingleThreadTaskRunner> MediaThreadTaskRunner() override;
+  scoped_refptr<base::SequencedTaskRunner> MediaThreadTaskRunner() override;
   base::WeakPtr<media::DecoderFactory> GetMediaDecoderFactory() override;
   void SetRenderingColorSpace(const gfx::ColorSpace& color_space) override;
   gfx::ColorSpace GetRenderingColorSpace() const override;
diff --git a/content/renderer/webgraphicscontext3d_provider_impl.cc b/content/renderer/webgraphicscontext3d_provider_impl.cc
index 1c38c5a..a5e3f415 100644
--- a/content/renderer/webgraphicscontext3d_provider_impl.cc
+++ b/content/renderer/webgraphicscontext3d_provider_impl.cc
@@ -27,13 +27,13 @@
   provider_->RemoveObserver(this);
 }
 
-bool WebGraphicsContext3DProviderImpl::BindToCurrentThread() {
+bool WebGraphicsContext3DProviderImpl::BindToCurrentSequence() {
   // TODO(danakj): Could plumb this result out to the caller so they know to
   // retry or not, if any client cared to know if it should retry or not.
   // Call AddObserver here instead of in constructor so that it's called on the
   // correct thread.
   provider_->AddObserver(this);
-  return provider_->BindToCurrentThread() == gpu::ContextResult::kSuccess;
+  return provider_->BindToCurrentSequence() == gpu::ContextResult::kSuccess;
 }
 
 gpu::InterfaceBase* WebGraphicsContext3DProviderImpl::InterfaceBase() {
diff --git a/content/renderer/webgraphicscontext3d_provider_impl.h b/content/renderer/webgraphicscontext3d_provider_impl.h
index 189c2d6..23015e0 100644
--- a/content/renderer/webgraphicscontext3d_provider_impl.h
+++ b/content/renderer/webgraphicscontext3d_provider_impl.h
@@ -42,7 +42,7 @@
   ~WebGraphicsContext3DProviderImpl() override;
 
   // WebGraphicsContext3DProvider implementation.
-  bool BindToCurrentThread() override;
+  bool BindToCurrentSequence() override;
   gpu::InterfaceBase* InterfaceBase() override;
   gpu::gles2::GLES2Interface* ContextGL() override;
   gpu::raster::RasterInterface* RasterInterface() override;
diff --git a/content/utility/BUILD.gn b/content/utility/BUILD.gn
index 362605e..a8f0f62 100644
--- a/content/utility/BUILD.gn
+++ b/content/utility/BUILD.gn
@@ -86,8 +86,8 @@
 
   if (is_chromeos_ash) {
     deps += [
-      "//ash/services/ime:sandbox_hook",
       "//chromeos/ash/components/assistant:buildflags",
+      "//chromeos/ash/services/ime:sandbox_hook",
       "//chromeos/services/tts:sandbox_hook",
     ]
     if (use_vaapi || use_v4l2_codec) {
diff --git a/content/utility/DEPS b/content/utility/DEPS
index 61d7d11..23a44487 100644
--- a/content/utility/DEPS
+++ b/content/utility/DEPS
@@ -1,6 +1,6 @@
 include_rules = [
   "+ash/components/arc/video_accelerator",
-  "+ash/services/ime",
+  "+chromeos/ash/services/ime",
   "+components/services/storage",
   "+content/child",
   "+content/public/utility",
diff --git a/content/utility/utility_main.cc b/content/utility/utility_main.cc
index c15f7b9..5936bfd 100644
--- a/content/utility/utility_main.cc
+++ b/content/utility/utility_main.cc
@@ -51,8 +51,8 @@
 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-#include "ash/services/ime/ime_sandbox_hook.h"
 #include "chromeos/ash/components/assistant/buildflags.h"
+#include "chromeos/ash/services/ime/ime_sandbox_hook.h"
 #include "chromeos/services/tts/tts_sandbox_hook.h"
 
 #if BUILDFLAG(ENABLE_CROS_LIBASSISTANT)
diff --git a/content/web_test/renderer/test_plugin.cc b/content/web_test/renderer/test_plugin.cc
index 7bab52e..4c5f45f1 100644
--- a/content/web_test/renderer/test_plugin.cc
+++ b/content/web_test/renderer/test_plugin.cc
@@ -176,7 +176,7 @@
   std::unique_ptr<blink::WebGraphicsContext3DProvider> context_provider =
       blink::Platform::Current()->CreateOffscreenGraphicsContext3DProvider(
           attrs, url, &gl_info);
-  if (context_provider && !context_provider->BindToCurrentThread())
+  if (context_provider && !context_provider->BindToCurrentSequence())
     context_provider = nullptr;
   if (context_provider) {
     gl_ = context_provider ? context_provider->ContextGL() : nullptr;
diff --git a/device/vr/openxr/openxr_render_loop.cc b/device/vr/openxr/openxr_render_loop.cc
index 730f107..b86ec49 100644
--- a/device/vr/openxr/openxr_render_loop.cc
+++ b/device/vr/openxr/openxr_render_loop.cc
@@ -526,7 +526,7 @@
 // StartContextProvider uses BindOnce to passthrough the start_runtime_callback
 // given to it from it's caller. OnContextProviderCreated must run the
 // start_runtime_callback, passing true on successful call to
-// BindToCurrentThread and false if not.
+// BindToCurrentSequence and false if not.
 void OpenXrRenderLoop::OnContextProviderCreated(
     StartRuntimeCallback start_runtime_callback,
     scoped_refptr<viz::ContextProvider> context_provider) {
@@ -534,7 +534,7 @@
   DCHECK_EQ(context_provider_, nullptr);
 
   const gpu::ContextResult context_result =
-      context_provider->BindToCurrentThread();
+      context_provider->BindToCurrentSequence();
   if (context_result != gpu::ContextResult::kSuccess) {
     std::move(start_runtime_callback).Run(false);
     return;
diff --git a/fuchsia_web/webengine/renderer/web_engine_media_renderer_factory.cc b/fuchsia_web/webengine/renderer/web_engine_media_renderer_factory.cc
index 8dd915a..9094e722 100644
--- a/fuchsia_web/webengine/renderer/web_engine_media_renderer_factory.cc
+++ b/fuchsia_web/webengine/renderer/web_engine_media_renderer_factory.cc
@@ -32,7 +32,7 @@
 
 std::vector<std::unique_ptr<media::VideoDecoder>>
 WebEngineMediaRendererFactory::CreateVideoDecoders(
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
     media::RequestOverlayInfoCB request_overlay_info_cb,
     const gfx::ColorSpace& target_color_space,
     media::GpuVideoAcceleratorFactories* gpu_factories) {
@@ -44,7 +44,7 @@
 }
 
 std::unique_ptr<media::Renderer> WebEngineMediaRendererFactory::CreateRenderer(
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
     const scoped_refptr<base::TaskRunner>& worker_task_runner,
     media::AudioRendererSink* audio_renderer_sink,
     media::VideoRendererSink* video_renderer_sink,
diff --git a/fuchsia_web/webengine/renderer/web_engine_media_renderer_factory.h b/fuchsia_web/webengine/renderer/web_engine_media_renderer_factory.h
index f88dc815..9f858bc6 100644
--- a/fuchsia_web/webengine/renderer/web_engine_media_renderer_factory.h
+++ b/fuchsia_web/webengine/renderer/web_engine_media_renderer_factory.h
@@ -39,7 +39,7 @@
 
   // RendererFactory interface.
   std::unique_ptr<media::Renderer> CreateRenderer(
-      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+      const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
       const scoped_refptr<base::TaskRunner>& worker_task_runner,
       media::AudioRendererSink* audio_renderer_sink,
       media::VideoRendererSink* video_renderer_sink,
@@ -48,7 +48,7 @@
 
  private:
   std::vector<std::unique_ptr<media::VideoDecoder>> CreateVideoDecoders(
-      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+      const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
       media::RequestOverlayInfoCB request_overlay_info_cb,
       const gfx::ColorSpace& target_color_space,
       media::GpuVideoAcceleratorFactories* gpu_factories);
diff --git a/gpu/command_buffer/service/BUILD.gn b/gpu/command_buffer/service/BUILD.gn
index 6548a93..e91f38bf 100644
--- a/gpu/command_buffer/service/BUILD.gn
+++ b/gpu/command_buffer/service/BUILD.gn
@@ -534,10 +534,7 @@
     defines = [ "VK_USE_PLATFORM_ANDROID_KHR" ]
     deps += [ "//third_party/libsync" ]
     if (enable_vulkan) {
-      deps += [
-        "//gpu/ipc/common:android_image_reader_utils",
-        "//gpu/vulkan",
-      ]
+      deps += [ "//gpu/vulkan" ]
     }
   }
 
diff --git a/gpu/command_buffer/service/image_reader_gl_owner.cc b/gpu/command_buffer/service/image_reader_gl_owner.cc
index 21bf881e..c5c8983 100644
--- a/gpu/command_buffer/service/image_reader_gl_owner.cc
+++ b/gpu/command_buffer/service/image_reader_gl_owner.cc
@@ -25,7 +25,6 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "gpu/command_buffer/service/abstract_texture.h"
 #include "gpu/config/gpu_finch_features.h"
-#include "gpu/ipc/common/android/android_image_reader_utils.h"
 #include "ui/gfx/android/android_surface_control_compat.h"
 #include "ui/gl/gl_fence_android_native_fence_sync.h"
 #include "ui/gl/gl_utils.h"
diff --git a/gpu/command_buffer/service/shared_image/gl_texture_android_image_representation.cc b/gpu/command_buffer/service/shared_image/gl_texture_android_image_representation.cc
index a93be5504..2ece75d 100644
--- a/gpu/command_buffer/service/shared_image/gl_texture_android_image_representation.cc
+++ b/gpu/command_buffer/service/shared_image/gl_texture_android_image_representation.cc
@@ -5,7 +5,7 @@
 #include "gpu/command_buffer/service/shared_image/gl_texture_android_image_representation.h"
 
 #include "gpu/command_buffer/service/texture_manager.h"
-#include "gpu/ipc/common/android/android_image_reader_utils.h"
+#include "ui/gl/android/egl_fence_utils.h"
 
 namespace gpu {
 
@@ -41,14 +41,14 @@
     base::ScopedFD write_sync_fd;
     if (!android_backing()->BeginRead(this, &write_sync_fd))
       return false;
-    if (!InsertEglFenceAndWait(std::move(write_sync_fd)))
+    if (!gl::InsertEglFenceAndWait(std::move(write_sync_fd)))
       return false;
   } else {
     base::ScopedFD sync_fd;
     if (!android_backing()->BeginWrite(&sync_fd))
       return false;
 
-    if (!InsertEglFenceAndWait(std::move(sync_fd)))
+    if (!gl::InsertEglFenceAndWait(std::move(sync_fd)))
       return false;
   }
 
@@ -64,7 +64,7 @@
   if (mode_ == RepresentationAccessMode::kNone)
     return;
 
-  base::ScopedFD sync_fd = CreateEglFenceAndExportFd();
+  base::ScopedFD sync_fd = gl::CreateEglFenceAndExportFd();
 
   // Pass this fd to its backing.
   if (mode_ == RepresentationAccessMode::kRead) {
diff --git a/gpu/command_buffer/service/shared_image/gl_texture_passthrough_android_image_representation.cc b/gpu/command_buffer/service/shared_image/gl_texture_passthrough_android_image_representation.cc
index 838e301..a3924005 100644
--- a/gpu/command_buffer/service/shared_image/gl_texture_passthrough_android_image_representation.cc
+++ b/gpu/command_buffer/service/shared_image/gl_texture_passthrough_android_image_representation.cc
@@ -5,7 +5,7 @@
 #include "gpu/command_buffer/service/shared_image/gl_texture_passthrough_android_image_representation.h"
 
 #include "gpu/command_buffer/service/texture_manager.h"
-#include "gpu/ipc/common/android/android_image_reader_utils.h"
+#include "ui/gl/android/egl_fence_utils.h"
 
 namespace gpu {
 
@@ -46,14 +46,14 @@
     base::ScopedFD write_sync_fd;
     if (!android_backing()->BeginRead(this, &write_sync_fd))
       return false;
-    if (!InsertEglFenceAndWait(std::move(write_sync_fd)))
+    if (!gl::InsertEglFenceAndWait(std::move(write_sync_fd)))
       return false;
   } else {
     base::ScopedFD sync_fd;
     if (!android_backing()->BeginWrite(&sync_fd))
       return false;
 
-    if (!InsertEglFenceAndWait(std::move(sync_fd)))
+    if (!gl::InsertEglFenceAndWait(std::move(sync_fd)))
       return false;
   }
 
@@ -69,7 +69,7 @@
   if (mode_ == RepresentationAccessMode::kNone)
     return;
 
-  base::ScopedFD sync_fd = CreateEglFenceAndExportFd();
+  base::ScopedFD sync_fd = gl::CreateEglFenceAndExportFd();
 
   // Pass this fd to its backing.
   if (mode_ == RepresentationAccessMode::kRead) {
diff --git a/gpu/command_buffer/service/shared_image/video_image_reader_image_backing.cc b/gpu/command_buffer/service/shared_image/video_image_reader_image_backing.cc
index 9423cceb..4503267 100644
--- a/gpu/command_buffer/service/shared_image/video_image_reader_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/video_image_reader_image_backing.cc
@@ -25,7 +25,6 @@
 #include "gpu/command_buffer/service/skia_utils.h"
 #include "gpu/command_buffer/service/texture_manager.h"
 #include "gpu/command_buffer/service/texture_owner.h"
-#include "gpu/ipc/common/android/android_image_reader_utils.h"
 #include "gpu/vulkan/vulkan_device_queue.h"
 #include "gpu/vulkan/vulkan_fence_helper.h"
 #include "gpu/vulkan/vulkan_function_pointers.h"
@@ -35,6 +34,7 @@
 #include "third_party/skia/include/core/SkPromiseImageTexture.h"
 #include "third_party/skia/include/gpu/GrBackendSemaphore.h"
 #include "third_party/skia/include/gpu/GrBackendSurface.h"
+#include "ui/gl/android/egl_fence_utils.h"
 #include "ui/gl/gl_image_ahardwarebuffer.h"
 #include "ui/gl/gl_utils.h"
 
@@ -218,7 +218,7 @@
   void EndAccess() override {
     DCHECK(scoped_hardware_buffer_);
 
-    base::ScopedFD sync_fd = CreateEglFenceAndExportFd();
+    base::ScopedFD sync_fd = gl::CreateEglFenceAndExportFd();
     scoped_hardware_buffer_->SetReadFence(std::move(sync_fd), true);
     base::AutoLockMaybe auto_lock(GetDrDcLockPtr());
     scoped_hardware_buffer_ = nullptr;
@@ -285,7 +285,7 @@
   void EndAccess() override {
     DCHECK(scoped_hardware_buffer_);
 
-    base::ScopedFD sync_fd = CreateEglFenceAndExportFd();
+    base::ScopedFD sync_fd = gl::CreateEglFenceAndExportFd();
     scoped_hardware_buffer_->SetReadFence(std::move(sync_fd), true);
     base::AutoLockMaybe auto_lock(GetDrDcLockPtr());
     scoped_hardware_buffer_ = nullptr;
diff --git a/gpu/ipc/client/command_buffer_proxy_impl.cc b/gpu/ipc/client/command_buffer_proxy_impl.cc
index 682ed9f..4cbf85b2d 100644
--- a/gpu/ipc/client/command_buffer_proxy_impl.cc
+++ b/gpu/ipc/client/command_buffer_proxy_impl.cc
@@ -47,7 +47,7 @@
     scoped_refptr<GpuChannelHost> channel,
     GpuMemoryBufferManager* gpu_memory_buffer_manager,
     int32_t stream_id,
-    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    scoped_refptr<base::SequencedTaskRunner> task_runner,
     base::SharedMemoryMapper* transfer_buffer_mapper)
     : channel_(std::move(channel)),
       gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
diff --git a/gpu/ipc/client/command_buffer_proxy_impl.h b/gpu/ipc/client/command_buffer_proxy_impl.h
index 80369c9..12f2fbfbb 100644
--- a/gpu/ipc/client/command_buffer_proxy_impl.h
+++ b/gpu/ipc/client/command_buffer_proxy_impl.h
@@ -25,6 +25,7 @@
 #include "base/memory/unsafe_shared_memory_region.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/threading/thread_checker.h"
 #include "gpu/command_buffer/client/gpu_control.h"
@@ -82,7 +83,7 @@
       scoped_refptr<GpuChannelHost> channel,
       GpuMemoryBufferManager* gpu_memory_buffer_manager,
       int32_t stream_id,
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+      scoped_refptr<base::SequencedTaskRunner> task_runner,
       base::SharedMemoryMapper* transfer_buffer_mapper = nullptr);
 
   CommandBufferProxyImpl(const CommandBufferProxyImpl&) = delete;
@@ -289,7 +290,7 @@
   raw_ptr<base::HistogramBase> uma_histogram_ensure_work_visible_duration_ =
       nullptr;
 
-  scoped_refptr<base::SingleThreadTaskRunner> callback_thread_;
+  scoped_refptr<base::SequencedTaskRunner> callback_thread_;
 
   // Optional shared memory mapper to use when creating transfer buffers.
   // TODO(1321521) remove this member and instead let callers of
diff --git a/gpu/ipc/common/BUILD.gn b/gpu/ipc/common/BUILD.gn
index 39cf771..ee2c3629 100644
--- a/gpu/ipc/common/BUILD.gn
+++ b/gpu/ipc/common/BUILD.gn
@@ -180,25 +180,6 @@
   }
 }
 
-if (is_android) {
-  source_set("android_image_reader_utils") {
-    sources = [
-      "android/android_image_reader_utils.cc",
-      "android/android_image_reader_utils.h",
-    ]
-    configs += [ "//gpu:gpu_implementation" ]
-    deps = [
-      "//base",
-      "//ui/gl",
-    ]
-    visibility = [
-      "//android_webview/browser/gfx",
-      "//gpu/*",
-      "//media/gpu:gpu",
-    ]
-  }
-}
-
 # Depend on this to use surface_handle.h without pulling in all of gpu ipc.
 source_set("surface_handle_type") {
   public = [ "surface_handle.h" ]
diff --git a/gpu/ipc/common/android/android_image_reader_utils.h b/gpu/ipc/common/android/android_image_reader_utils.h
deleted file mode 100644
index 7938930..0000000
--- a/gpu/ipc/common/android/android_image_reader_utils.h
+++ /dev/null
@@ -1,21 +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 GPU_IPC_COMMON_ANDROID_ANDROID_IMAGE_READER_UTILS_H_
-#define GPU_IPC_COMMON_ANDROID_ANDROID_IMAGE_READER_UTILS_H_
-
-#include "base/files/scoped_file.h"
-#include "gpu/gpu_export.h"
-
-namespace gpu {
-
-// Create and inserts an egl fence and exports a ScopedFD from it.
-GPU_EXPORT base::ScopedFD CreateEglFenceAndExportFd();
-
-// Create and insert an EGL fence and imports the provided fence fd.
-GPU_EXPORT bool InsertEglFenceAndWait(base::ScopedFD acquire_fence_fd);
-
-}  // namespace gpu
-
-#endif  // GPU_IPC_COMMON_ANDROID_ANDROID_IMAGE_READER_UTILS_H_
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg
index 4cce0f0..d471cf29 100644
--- a/infra/config/generated/luci/cr-buildbucket.cfg
+++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -2734,6 +2734,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -2821,6 +2825,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -5240,6 +5248,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -5327,6 +5339,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -18580,6 +18596,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -18667,6 +18687,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -18754,6 +18778,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -18841,6 +18869,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -18928,6 +18960,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -19015,6 +19051,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -19102,6 +19142,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -19189,6 +19233,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -19276,6 +19324,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -19363,6 +19415,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -19450,6 +19506,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -19537,6 +19597,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -19624,6 +19688,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -19711,6 +19779,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -19798,6 +19870,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -19883,6 +19959,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -19958,6 +20038,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -20045,6 +20129,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -20132,6 +20220,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -20219,6 +20311,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -20306,6 +20402,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -20392,6 +20492,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -20478,6 +20582,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -20564,6 +20672,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -20639,6 +20751,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -20726,6 +20842,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -20811,6 +20931,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -20898,6 +21022,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -20985,6 +21113,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -21072,6 +21204,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -21159,6 +21295,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -21246,6 +21386,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -21331,6 +21475,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -21406,6 +21554,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -21495,6 +21647,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -21584,6 +21740,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -40917,6 +41077,10 @@
         value: 10
       }
       experiments {
+        key: "luci.buildbucket.omit_python2"
+        value: 100
+      }
+      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
diff --git a/infra/config/subprojects/chromium/ci/chromium.clang.star b/infra/config/subprojects/chromium/ci/chromium.clang.star
index bb64041..5f92b47 100644
--- a/infra/config/subprojects/chromium/ci/chromium.clang.star
+++ b/infra/config/subprojects/chromium/ci/chromium.clang.star
@@ -25,9 +25,6 @@
     },
     service_account = ci.DEFAULT_SERVICE_ACCOUNT,
     sheriff_rotations = sheriff_rotations.CHROMIUM_CLANG,
-
-    # TODO(crbug.com/1362440): remove this.
-    omit_python2 = False,
 )
 
 consoles.console_view(
diff --git a/ios/chrome/browser/crash_report/BUILD.gn b/ios/chrome/browser/crash_report/BUILD.gn
index b47fce3..c9c2affe 100644
--- a/ios/chrome/browser/crash_report/BUILD.gn
+++ b/ios/chrome/browser/crash_report/BUILD.gn
@@ -81,6 +81,7 @@
     "//ios/chrome/browser/sessions:serialisation",
     "//ios/chrome/browser/sessions:session_service",
     "//ios/chrome/browser/ui:feature_flags",
+    "//ios/chrome/browser/ui/icons:symbols",
     "//ios/chrome/browser/ui/main:scene_state_header",
     "//ios/chrome/browser/web_state_list",
     "//ios/web",
diff --git a/ios/chrome/browser/crash_report/DEPS b/ios/chrome/browser/crash_report/DEPS
index 6a33ca5..d33ba6d 100644
--- a/ios/chrome/browser/crash_report/DEPS
+++ b/ios/chrome/browser/crash_report/DEPS
@@ -8,6 +8,7 @@
 specific_include_rules = {
   # TODO(crbug.com/1294160): Remove this dependency.
   "^crash_restore_helper.mm": [
+    "+ios/chrome/browser/ui/icons",
     "+ios/chrome/browser/ui/main/scene_state.h",
     "+ios/chrome/browser/ui/main/scene_state_browser_agent.h",
     "+ios/chrome/browser/ui/ui_feature_flags.h",
diff --git a/ios/chrome/browser/crash_report/crash_restore_helper.mm b/ios/chrome/browser/crash_report/crash_restore_helper.mm
index eeaa465..7aaaf090 100644
--- a/ios/chrome/browser/crash_report/crash_restore_helper.mm
+++ b/ios/chrome/browser/crash_report/crash_restore_helper.mm
@@ -35,6 +35,7 @@
 #import "ios/chrome/browser/sessions/session_restoration_browser_agent.h"
 #import "ios/chrome/browser/sessions/session_service_ios.h"
 #import "ios/chrome/browser/sessions/session_window_ios.h"
+#import "ios/chrome/browser/ui/icons/chrome_symbol.h"
 #import "ios/chrome/browser/ui/main/scene_state.h"
 #import "ios/chrome/browser/ui/main/scene_state_browser_agent.h"
 #import "ios/chrome/browser/ui/ui_feature_flags.h"
@@ -74,9 +75,6 @@
 // The size of the symbol image.
 const CGFloat kSymbolImagePointSize = 18;
 
-// The name if the popup symbol.
-NSString* const kRestoreSessionSymbol = @"exclamationmark.triangle.fill";
-
 // The name for directory which contains all session backup subdirectories for
 // multiple sessions.
 const base::FilePath::CharType kSessionBackupDirectory[] =
@@ -157,12 +155,8 @@
 
   ui::ImageModel GetIcon() const override {
     if (icon_.IsEmpty()) {
-      UIImageSymbolConfiguration* configuration = [UIImageSymbolConfiguration
-          configurationWithPointSize:kSymbolImagePointSize
-                              weight:UIImageSymbolWeightMedium
-                               scale:UIImageSymbolScaleMedium];
-      UIImage* image = [UIImage systemImageNamed:kRestoreSessionSymbol
-                               withConfiguration:configuration];
+      UIImage* image =
+          DefaultSymbolWithPointSize(kWarningFillSymbol, kSymbolImagePointSize);
       icon_ = gfx::Image(image);
     }
     return ui::ImageModel::FromImage(icon_);
diff --git a/ios/chrome/browser/ui/authentication/tangible_sync/tangible_sync_view_controller.mm b/ios/chrome/browser/ui/authentication/tangible_sync/tangible_sync_view_controller.mm
index ec318a8e4..49c1059 100644
--- a/ios/chrome/browser/ui/authentication/tangible_sync/tangible_sync_view_controller.mm
+++ b/ios/chrome/browser/ui/authentication/tangible_sync/tangible_sync_view_controller.mm
@@ -129,7 +129,7 @@
   }
 }
 
-- (void)setprimaryIdentityAvatarAccessibilityLabel:
+- (void)setPrimaryIdentityAvatarAccessibilityLabel:
     (NSString*)primaryIdentityAvatarAccessibilityLabel {
   if (_primaryIdentityAvatarAccessibilityLabel !=
       primaryIdentityAvatarAccessibilityLabel) {
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm
index 469bda92..a33d042 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm
@@ -110,15 +110,6 @@
 // Estimated TableView row height.
 const CGFloat kEstimatedRowHeight = 65.0;
 
-// TableView rows that are hidden by the NavigationBar, causing them to be
-// "visible" for the tableView but not for the user. This is used to calculate
-// the top most visibile table view indexPath row.
-// TODO(crbug.com/879001): This value is aproximate based on the standard (no
-// dynamic type) height. If the dynamic font is too large or too small it will
-// result in a small offset on the cache, in order to prevent this we need to
-// calculate this value dynamically.
-const int kRowsHiddenByNavigationBar = 3;
-
 // Returns a vector of all URLs in `nodes`.
 std::vector<GURL> GetUrlsToOpen(const std::vector<const BookmarkNode*>& nodes) {
   std::vector<GURL> urls;
@@ -1277,14 +1268,8 @@
   if (topMostIndexPath.row == 0)
     return 0;
 
-  // To avoid an index out of bounds, check if there are less or equal
-  // kRowsHiddenByNavigationBar than number of visibleIndexPaths.
-  if ([visibleIndexPaths count] <= kRowsHiddenByNavigationBar)
-    return 0;
-
-  // Return the first visible row not covered by the NavigationBar.
-  topMostIndexPath =
-      [visibleIndexPaths objectAtIndex:kRowsHiddenByNavigationBar];
+  // Return the first visible row.
+  topMostIndexPath = [visibleIndexPaths objectAtIndex:0];
   return topMostIndexPath.row;
 }
 
diff --git a/ios/chrome/browser/ui/first_run/fre_field_trial.cc b/ios/chrome/browser/ui/first_run/fre_field_trial.cc
index fd01f8f..9ed6495 100644
--- a/ios/chrome/browser/ui/first_run/fre_field_trial.cc
+++ b/ios/chrome/browser/ui/first_run/fre_field_trial.cc
@@ -118,11 +118,11 @@
     case version_info::Channel::UNKNOWN:
     case version_info::Channel::CANARY:
     case version_info::Channel::DEV:
+    case version_info::Channel::BETA:
       for (auto& [id, weight] : weight_by_id) {
         weight = 20;
       };
       break;
-    case version_info::Channel::BETA:
     case version_info::Channel::STABLE:
       break;
   }
diff --git a/ios/chrome/browser/ui/icons/BUILD.gn b/ios/chrome/browser/ui/icons/BUILD.gn
index e51f901..d4d767e 100644
--- a/ios/chrome/browser/ui/icons/BUILD.gn
+++ b/ios/chrome/browser/ui/icons/BUILD.gn
@@ -92,6 +92,16 @@
   frameworks = [ "UIKit.framework" ]
 }
 
+source_set("location_bar_icons") {
+  configs += [ "//build/config/compiler:enable_arc" ]
+  sources = [
+    "location_bar_icon.h",
+    "location_bar_icon.mm",
+  ]
+  deps = [ ":symbols" ]
+  frameworks = [ "UIKit.framework" ]
+}
+
 source_set("symbols") {
   configs += [ "//build/config/compiler:enable_arc" ]
   sources = [
@@ -118,7 +128,6 @@
     "//ios/chrome/browser/ui/icons/resources:square_bullet_square",
     "//ios/chrome/browser/ui/icons/resources:square_number",
     "//ios/chrome/browser/ui/icons/resources:translate",
-    "//ui/base",
     ios_branded_icons,
   ]
   frameworks = [
diff --git a/ios/chrome/browser/ui/icons/chrome_symbol.h b/ios/chrome/browser/ui/icons/chrome_symbol.h
index 277bd79..c028cab 100644
--- a/ios/chrome/browser/ui/icons/chrome_symbol.h
+++ b/ios/chrome/browser/ui/icons/chrome_symbol.h
@@ -62,6 +62,9 @@
 extern NSString* const kBookmarksSymbol;
 extern NSString* const kSyncErrorSymbol;
 extern NSString* const kMenuSymbol;
+extern NSString* const kSortSymbol;
+extern NSString* const kBackSymbol;
+extern NSString* const kForwardSymbol;
 
 // The corner radius of the symbol with a colorful background.
 extern const CGFloat kColorfulBackgroundSymbolCornerRadius;
diff --git a/ios/chrome/browser/ui/icons/chrome_symbol.mm b/ios/chrome/browser/ui/icons/chrome_symbol.mm
index 0414296..da2fc13 100644
--- a/ios/chrome/browser/ui/icons/chrome_symbol.mm
+++ b/ios/chrome/browser/ui/icons/chrome_symbol.mm
@@ -102,6 +102,9 @@
 NSString* const kSyncErrorSymbol =
     @"exclamationmark.arrow.triangle.2.circlepath";
 NSString* const kMenuSymbol = @"ellipsis";
+NSString* const kSortSymbol = @"arrow.up.arrow.down";
+NSString* const kBackSymbol = @"arrow.backward";
+NSString* const kForwardSymbol = @"arrow.forward";
 
 const CGFloat kColorfulBackgroundSymbolCornerRadius = 7;
 
diff --git a/ios/chrome/browser/ui/icons/item_icon.h b/ios/chrome/browser/ui/icons/item_icon.h
index 3de8eaf..d373c002 100644
--- a/ios/chrome/browser/ui/icons/item_icon.h
+++ b/ios/chrome/browser/ui/icons/item_icon.h
@@ -11,7 +11,7 @@
 extern const CGFloat kSymbolAccessoryPointSize;
 
 // Specific symbols used to create items.
-extern NSString* const kExternalLinkSmbol;
+extern NSString* const kExternalLinkSymbol;
 extern NSString* const kChevronForwardSymbol;
 
 #endif  // IOS_CHROME_BROWSER_UI_ICONS_ITEM_ICON_H_
diff --git a/ios/chrome/browser/ui/icons/item_icon.mm b/ios/chrome/browser/ui/icons/item_icon.mm
index d64095f..64c9d37 100644
--- a/ios/chrome/browser/ui/icons/item_icon.mm
+++ b/ios/chrome/browser/ui/icons/item_icon.mm
@@ -10,5 +10,5 @@
 
 const CGFloat kSymbolAccessoryPointSize = 18.;
 
-NSString* const kExternalLinkSmbol = @"arrow.up.forward.square";
+NSString* const kExternalLinkSymbol = @"arrow.up.forward.square";
 NSString* const kChevronForwardSymbol = @"chevron.forward";
diff --git a/ios/chrome/browser/ui/icons/location_bar_icon.h b/ios/chrome/browser/ui/icons/location_bar_icon.h
new file mode 100644
index 0000000..7a6a3d6
--- /dev/null
+++ b/ios/chrome/browser/ui/icons/location_bar_icon.h
@@ -0,0 +1,13 @@
+// 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.
+
+#ifndef IOS_CHROME_BROWSER_UI_ICONS_LOCATION_BAR_ICON_H_
+#define IOS_CHROME_BROWSER_UI_ICONS_LOCATION_BAR_ICON_H_
+
+#import <Foundation/Foundation.h>
+
+// Default symbol names.
+extern NSString* const kSecureLocationBarSymbol;
+
+#endif  // IOS_CHROME_BROWSER_UI_ICONS_LOCATION_BAR_ICON_H_
diff --git a/ios/chrome/browser/ui/icons/location_bar_icon.mm b/ios/chrome/browser/ui/icons/location_bar_icon.mm
new file mode 100644
index 0000000..6d080bb
--- /dev/null
+++ b/ios/chrome/browser/ui/icons/location_bar_icon.mm
@@ -0,0 +1,12 @@
+// 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.
+
+#import "ios/chrome/browser/ui/icons/location_bar_icon.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+// Default symbol names.
+NSString* const kSecureLocationBarSymbol = @"lock.fill";
diff --git a/ios/chrome/browser/ui/icons/settings_icon.h b/ios/chrome/browser/ui/icons/settings_icon.h
index e051243..61bca44 100644
--- a/ios/chrome/browser/ui/icons/settings_icon.h
+++ b/ios/chrome/browser/ui/icons/settings_icon.h
@@ -22,6 +22,8 @@
 extern NSString* const kDefaultBrowserSymbol;
 extern NSString* const kDiscoverSymbol;
 extern NSString* const kBellSymbol;
+extern NSString* const kCachedDataSymbol;
+extern NSString* const kAutofillDataSymbol;
 
 // Returns a SF symbol named `symbol_name` configured for the Settings root
 // screen.
diff --git a/ios/chrome/browser/ui/icons/settings_icon.mm b/ios/chrome/browser/ui/icons/settings_icon.mm
index afce744..615fdd7 100644
--- a/ios/chrome/browser/ui/icons/settings_icon.mm
+++ b/ios/chrome/browser/ui/icons/settings_icon.mm
@@ -25,6 +25,8 @@
 NSString* const kDefaultBrowserSymbol = @"app.badge.checkmark";
 NSString* const kDiscoverSymbol = @"flame";
 NSString* const kBellSymbol = @"bell";
+NSString* const kCachedDataSymbol = @"photo.on.rectangle";
+NSString* const kAutofillDataSymbol = @"wand.and.rays";
 
 UIImage* DefaultSettingsRootSymbol(NSString* symbol_name) {
   return DefaultSymbolWithPointSize(symbol_name,
diff --git a/ios/chrome/browser/ui/ntp/feed_header_view_controller.mm b/ios/chrome/browser/ui/ntp/feed_header_view_controller.mm
index db97e45..0db96d8 100644
--- a/ios/chrome/browser/ui/ntp/feed_header_view_controller.mm
+++ b/ios/chrome/browser/ui/ntp/feed_header_view_controller.mm
@@ -67,10 +67,6 @@
 // TODO(crbug.com/1277974): Remove this when Web Channels is launched.
 NSString* kDiscoverMenuIcon = @"infobar_settings_icon";
 
-// Specific symbols used in the feed header.
-NSString* kSortArrowFeedSymbol = @"arrow.up.arrow.down";
-NSString* kEllipsisFeedSymbol = @"ellipsis";
-
 // The size of feed symbol images.
 NSInteger kFeedSymbolPointSize = 17;
 
@@ -369,7 +365,7 @@
       l10n_util::GetNSString(IDS_IOS_DISCOVER_FEED_MENU_ACCESSIBILITY_LABEL);
   if ([self.feedControlDelegate isFollowingFeedAvailable]) {
     [menuButton setImage:DefaultSymbolTemplateWithPointSize(
-                             kEllipsisFeedSymbol, kFeedSymbolPointSize)
+                             kMenuSymbol, kFeedSymbolPointSize)
                 forState:UIControlStateNormal];
     menuButton.backgroundColor =
         [[UIColor colorNamed:kGrey200Color] colorWithAlphaComponent:0.8];
@@ -400,7 +396,7 @@
   sortButton.accessibilityIdentifier = kNTPFeedHeaderSortButtonIdentifier;
   sortButton.accessibilityLabel =
       l10n_util::GetNSString(IDS_IOS_FEED_SORT_ACCESSIBILITY_LABEL);
-  [sortButton setImage:DefaultSymbolTemplateWithPointSize(kSortArrowFeedSymbol,
+  [sortButton setImage:DefaultSymbolTemplateWithPointSize(kSortSymbol,
                                                           kFeedSymbolPointSize)
               forState:UIControlStateNormal];
   sortButton.showsMenuAsPrimaryAction = YES;
diff --git a/ios/chrome/browser/ui/omnibox/BUILD.gn b/ios/chrome/browser/ui/omnibox/BUILD.gn
index c1d5f3b..1e3eba6 100644
--- a/ios/chrome/browser/ui/omnibox/BUILD.gn
+++ b/ios/chrome/browser/ui/omnibox/BUILD.gn
@@ -105,6 +105,7 @@
   ]
   deps = [
     "//base",
+    "//ios/chrome/browser/ui/icons:location_bar_icons",
     "//ios/chrome/browser/ui/icons:symbols",
   ]
 }
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_icon_type.mm b/ios/chrome/browser/ui/omnibox/omnibox_icon_type.mm
index f6b00c68..bba46dd 100644
--- a/ios/chrome/browser/ui/omnibox/omnibox_icon_type.mm
+++ b/ios/chrome/browser/ui/omnibox/omnibox_icon_type.mm
@@ -3,21 +3,15 @@
 // found in the LICENSE file.
 
 #import "ios/chrome/browser/ui/omnibox/omnibox_icon_type.h"
-#import "ios/chrome/browser/ui/icons/chrome_symbol.h"
 
 #import "base/notreached.h"
+#import "ios/chrome/browser/ui/icons/chrome_symbol.h"
+#import "ios/chrome/browser/ui/icons/location_bar_icon.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
 #endif
 
-namespace {
-
-// Specific symbol name for the location bar.
-NSString* kSecureLocationBarSymbol = @"lock.fill";
-
-}  // namespace
-
 NSString* GetLocationBarSecurityIconTypeAssetName(
     LocationBarSecurityIconType iconType) {
   switch (iconType) {
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/destination_usage_history/destination_usage_history.h b/ios/chrome/browser/ui/popup_menu/overflow_menu/destination_usage_history/destination_usage_history.h
index 9eeec7f..cb0dedd3 100644
--- a/ios/chrome/browser/ui/popup_menu/overflow_menu/destination_usage_history/destination_usage_history.h
+++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/destination_usage_history/destination_usage_history.h
@@ -47,6 +47,9 @@
 
 - (instancetype)init NS_UNAVAILABLE;
 
+// Disconnect the Destination Usage History.
+- (void)disconnect;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_POPUP_MENU_OVERFLOW_MENU_DESTINATION_USAGE_HISTORY_DESTINATION_USAGE_HISTORY_H_
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/destination_usage_history/destination_usage_history.mm b/ios/chrome/browser/ui/popup_menu/overflow_menu/destination_usage_history/destination_usage_history.mm
index 703b72c..46421db 100644
--- a/ios/chrome/browser/ui/popup_menu/overflow_menu/destination_usage_history/destination_usage_history.mm
+++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/destination_usage_history/destination_usage_history.mm
@@ -183,6 +183,8 @@
 // B's numClicks exceeds A's.
 @implementation DestinationUsageHistory
 
+#pragma mark - Initializers
+
 - (instancetype)initWithPrefService:(PrefService*)prefService {
   if (self = [super init])
     _prefService = prefService;
@@ -190,6 +192,16 @@
   return self;
 }
 
+- (void)dealloc {
+  DCHECK(!self.prefService) << "-disconnect needs to be called before -dealloc";
+}
+
+#pragma mark - Disconnect
+
+- (void)disconnect {
+  self.prefService = nullptr;
+}
+
 #pragma mark - Public
 
 - (std::vector<overflow_menu::Destination>)
@@ -234,8 +246,8 @@
 // Track click for `destination` and associate it with TodaysDay().
 - (void)trackDestinationClick:(overflow_menu::Destination)destination
      numAboveFoldDestinations:(int)numAboveFoldDestinations {
-  DCHECK(self.prefService);
-  // Exit early if there's no pref service; this is not expected to happen.
+  // Exit early if there's no pref service. May happen during the application
+  // shutdown.
   if (!self.prefService)
     return;
 
@@ -269,6 +281,11 @@
 // Injects a default number of clicks for all destinations in the history
 // dictonary.
 - (void)injectDefaultNumClicksForAllDestinations {
+  // Exit early if there's no pref service. May happen during the application
+  // shutdown.
+  if (!self.prefService)
+    return;
+
   DCHECK_GT(kDampening, 1.0);
   DCHECK_GT(kInitialBufferNumClicks, 1);
 
@@ -292,6 +309,11 @@
 // saves back to prefs. Returns true if expired usage data was found/removed,
 // false otherwise.
 - (void)deleteExpiredData {
+  // Exit early if there's no pref service. May happen during the application
+  // shutdown.
+  if (!self.prefService)
+    return;
+
   const base::Value::Dict& history =
       self.prefService->GetDict(prefs::kOverflowMenuDestinationUsageHistory);
 
@@ -312,6 +334,11 @@
 
 // Fetches the current ranking saved in prefs and returns it.
 - (const base::Value::List*)fetchCurrentRanking {
+  // Exit early if there's no pref service. May happen during the application
+  // shutdown.
+  if (!self.prefService)
+    return nullptr;
+
   const base::Value::Dict& history =
       self.prefService->GetDict(prefs::kOverflowMenuDestinationUsageHistory);
 
@@ -352,11 +379,16 @@
 // (int). Only usage data within previous `window` days will be included in the
 // returned result.
 - (base::Value::Dict)flattenedHistoryWithinWindow:(int)window {
+  base::Value::Dict flatHistory;
+
+  // Exit early if there's no pref service. May happen during the application
+  // shutdown.
+  if (!self.prefService)
+    return flatHistory;
+
   const base::Value::Dict& history =
       self.prefService->GetDict(prefs::kOverflowMenuDestinationUsageHistory);
 
-  base::Value::Dict flatHistory;
-
   for (auto&& [day, dayHistory] : history) {
     // Skip over entry corresponding to previous ranking.
     if (day == kRankingKey) {
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/destination_usage_history/destination_usage_history_unittest.mm b/ios/chrome/browser/ui/popup_menu/overflow_menu/destination_usage_history/destination_usage_history_unittest.mm
index aef2af52..7dc7d62 100644
--- a/ios/chrome/browser/ui/popup_menu/overflow_menu/destination_usage_history/destination_usage_history_unittest.mm
+++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/destination_usage_history/destination_usage_history_unittest.mm
@@ -31,6 +31,11 @@
   DestinationUsageHistoryTest() {}
 
  protected:
+  void TearDown() override {
+    [destination_usage_history_ disconnect];
+    PlatformTest::TearDown();
+  }
+
   // Creates CreateDestinationUsageHistory with empty pref data.
   DestinationUsageHistory* CreateDestinationUsageHistory() {
     CreatePrefs();
@@ -163,6 +168,17 @@
       pref_service->HasPrefPath(prefs::kOverflowMenuDestinationUsageHistory));
 }
 
+// Tests DestinationUsageHistory::disconnect correctly nullifies the
+// prefService.
+TEST_F(DestinationUsageHistoryTest, DestroysPrefServiceOnDisconnect) {
+  DestinationUsageHistory* destination_usage_history =
+      CreateDestinationUsageHistory();
+
+  [destination_usage_history disconnect];
+
+  EXPECT_EQ(destination_usage_history.prefService, nullptr);
+}
+
 // Tests that a new destination click is incremented and written to Chrome
 // Prefs.
 TEST_F(DestinationUsageHistoryTest, HandlesNewDestinationClickAndAddToPrefs) {
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_destination_list.swift b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_destination_list.swift
index be7484f..8645f77 100644
--- a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_destination_list.swift
+++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_destination_list.swift
@@ -80,7 +80,7 @@
     }
     .animation(nil)
     .background(
-      uiConfiguration.highlightDestinationsRow ? Color("destination_highlight_color") : Color.clear
+      Color("destination_highlight_color").opacity(uiConfiguration.highlightDestinationsRow ? 1 : 0)
     )
     .animation(.linear(duration: kMaterialDuration3))
     .onPreferenceChange(ScrollViewLeadingOffset.self) { newOffset in
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm
index 23ace8fb..d1800041 100644
--- a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm
+++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm
@@ -284,7 +284,10 @@
   }
 
   self.followBrowserAgent = nullptr;
+
+  [self.destinationUsageHistory disconnect];
   self.destinationUsageHistory = nil;
+
   self.webState = nullptr;
   self.webStateList = nullptr;
 
diff --git a/ios/chrome/browser/ui/settings/clear_browsing_data/BUILD.gn b/ios/chrome/browser/ui/settings/clear_browsing_data/BUILD.gn
index 495101f..2ee8637 100644
--- a/ios/chrome/browser/ui/settings/clear_browsing_data/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/clear_browsing_data/BUILD.gn
@@ -55,6 +55,7 @@
     "//ios/chrome/browser/ui/coordinators:chrome_coordinators",
     "//ios/chrome/browser/ui/elements:elements_internal",
     "//ios/chrome/browser/ui/icons",
+    "//ios/chrome/browser/ui/icons:settings_icons",
     "//ios/chrome/browser/ui/icons:symbols",
     "//ios/chrome/browser/ui/list_model",
     "//ios/chrome/browser/ui/resources:legacy_password_key",
diff --git a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_manager.mm b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_manager.mm
index cdca7f0eb..1027896 100644
--- a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_manager.mm
+++ b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_manager.mm
@@ -47,6 +47,7 @@
 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
 #import "ios/chrome/browser/ui/icons/chrome_icon.h"
 #import "ios/chrome/browser/ui/icons/chrome_symbol.h"
+#import "ios/chrome/browser/ui/icons/settings_icon.h"
 #import "ios/chrome/browser/ui/list_model/list_model.h"
 #import "ios/chrome/browser/ui/settings/cells/clear_browsing_data_constants.h"
 #import "ios/chrome/browser/ui/settings/cells/search_engine_item.h"
@@ -94,10 +95,6 @@
 // The size of the symbol image used in the 'Clear Browsing Data' view.
 const CGFloat kSymbolPointSize = 22;
 
-// Specific symbols used in the 'Clear Browsing Data' view.
-NSString* const kCachedDataSymbol = @"photo.on.rectangle";
-NSString* const kAutofillDataSymbol = @"wand.and.rays";
-
 // Returns the symbol coresponding to the given itemType.
 UIImage* SymbolForItemType(ClearBrowsingDataItemType itemType) {
   UIImage* symbol = nil;
diff --git a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.mm b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.mm
index e9297c9..6f7bef15 100644
--- a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.mm
+++ b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.mm
@@ -318,7 +318,7 @@
   TableViewImageItem* googleActivityControlsItem =
       [[TableViewImageItem alloc] initWithType:GoogleActivityControlsItemType];
   googleActivityControlsItem.accessoryView = [[UIImageView alloc]
-      initWithImage:DefaultSymbolWithConfiguration(kExternalLinkSmbol,
+      initWithImage:DefaultSymbolWithConfiguration(kExternalLinkSymbol,
                                                    AccessoryConfiguration())];
   googleActivityControlsItem.accessoryView.tintColor =
       [UIColor colorNamed:kTextQuaternaryColor];
@@ -334,7 +334,7 @@
   TableViewImageItem* dataFromChromeSyncItem =
       [[TableViewImageItem alloc] initWithType:DataFromChromeSync];
   dataFromChromeSyncItem.accessoryView = [[UIImageView alloc]
-      initWithImage:DefaultSymbolWithConfiguration(kExternalLinkSmbol,
+      initWithImage:DefaultSymbolWithConfiguration(kExternalLinkSymbol,
                                                    AccessoryConfiguration())];
   dataFromChromeSyncItem.accessoryView.tintColor =
       [UIColor colorNamed:kTextQuaternaryColor];
diff --git a/ios/chrome/browser/ui/sharing/sharing_coordinator.mm b/ios/chrome/browser/ui/sharing/sharing_coordinator.mm
index c6bbbd9f..3faa67a93 100644
--- a/ios/chrome/browser/ui/sharing/sharing_coordinator.mm
+++ b/ios/chrome/browser/ui/sharing/sharing_coordinator.mm
@@ -6,10 +6,13 @@
 
 #import <MaterialComponents/MaterialSnackbar.h>
 
+#import "base/files/file_util.h"
 #import "base/ios/block_types.h"
+#import "base/mac/foundation_util.h"
 #import "base/metrics/histogram_macros.h"
 #import "base/strings/sys_string_conversions.h"
 #import "base/task/thread_pool.h"
+#import "base/threading/scoped_blocking_call.h"
 #import "ios/chrome/browser/main/browser.h"
 #import "ios/chrome/browser/open_in/open_in_tab_helper.h"
 #import "ios/chrome/browser/ui/activity_services/activity_params.h"
@@ -43,6 +46,52 @@
 // The path in the temp directory containing documents that are to be opened in
 // other applications.
 static NSString* const kDocumentsTemporaryPath = @"OpenIn";
+
+// Returns the temporary path where documents are stored.
+NSString* GetTemporaryDocumentDirectory() {
+  return [NSTemporaryDirectory()
+      stringByAppendingPathComponent:kDocumentsTemporaryPath];
+}
+
+// Removes all the stored files at `path`.
+void RemoveAllStoredDocumentsAtPath(NSString* path) {
+  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+                                                base::BlockingType::WILL_BLOCK);
+  NSFileManager* file_manager = [NSFileManager defaultManager];
+
+  NSError* error = nil;
+  NSArray<NSString*>* document_files =
+      [file_manager contentsOfDirectoryAtPath:path error:&error];
+  if (!document_files) {
+    DLOG(ERROR) << "Failed to get content of directory at path: "
+                << base::SysNSStringToUTF8([error description]);
+    return;
+  }
+
+  for (NSString* filename in document_files) {
+    NSString* file_path = [path stringByAppendingPathComponent:filename];
+    if (![file_manager removeItemAtPath:file_path error:&error]) {
+      DLOG(ERROR) << "Failed to remove file: "
+                  << base::SysNSStringToUTF8([error description]);
+    }
+  }
+}
+
+// Ensures the destination directory is created and any contained obsolete files
+// are deleted. Returns YES if the directory is created successfully.
+BOOL CreateDestinationDirectoryAndRemoveObsoleteFiles() {
+  NSString* temporary_directory_path = GetTemporaryDocumentDirectory();
+  base::File::Error error;
+  if (!CreateDirectoryAndGetError(
+          base::mac::NSStringToFilePath(temporary_directory_path), &error)) {
+    DLOG(ERROR) << "Error creating destination dir: " << error;
+    return NO;
+  }
+  // Remove all documents that might be still on temporary storage.
+  RemoveAllStoredDocumentsAtPath(temporary_directory_path);
+  return YES;
+}
+
 }  // namespace
 
 @interface SharingCoordinator () <ActivityServicePositioner,
@@ -148,12 +197,16 @@
       self.browser->GetWebStateList()->GetActiveWebState();
   if (currentWebState && OpenInTabHelper::ShouldDownload(currentWebState) &&
       IsOpenInActivitiesInShareButtonEnabled()) {
-    self.dispatcher = self.browser->GetCommandDispatcher();
-    [self.dispatcher
-        startDispatchingToTarget:self
-                     forProtocol:@protocol(ShareDownloadOverlayCommands)];
-    [self startDisplayDownloadOverlayOnWebView:currentWebState];
-    [self startDownloadFromWebState:currentWebState];
+    // Creating the directory can block the main thread, so perform it on a
+    // background sequence, then on current sequence complete the workflow.
+    __weak SharingCoordinator* weakSelf = self;
+    base::ThreadPool::PostTaskAndReplyWithResult(
+        FROM_HERE, {base::TaskPriority::USER_VISIBLE, base::MayBlock()},
+        base::BindOnce(&CreateDestinationDirectoryAndRemoveObsoleteFiles),
+        base::BindOnce(^(BOOL directoryCreated) {
+          [weakSelf startDownloadWithExistingDirectory:directoryCreated
+                                              webState:currentWebState];
+        }));
   } else {
     [self startActivityService];
   }
@@ -162,7 +215,6 @@
 - (void)stop {
   [self activityServiceDidEndPresenting];
   [self hideQRCode];
-  [self.dispatcher stopDispatchingToTarget:self];
   self.originView = nil;
 }
 
@@ -212,6 +264,18 @@
 
 #pragma mark - Private Methods
 
+// Starts download only if the final directory is created, if not created, shows
+// the share menu without file options.
+- (void)startDownloadWithExistingDirectory:(BOOL)directoryCreated
+                                  webState:(web::WebState*)webState {
+  if (directoryCreated) {
+    [self startDisplayDownloadOverlayOnWebView:webState];
+    [self startDownloadFromWebState:webState];
+  } else {
+    [self startActivityService];
+  }
+}
+
 // Starts the share menu feature.
 - (void)startActivityService {
   self.activityServiceCoordinator = [[ActivityServiceCoordinator alloc]
@@ -237,8 +301,7 @@
 // Starts downloading the file currently displayed at path `self.filePath`.
 - (void)startDownloadFromWebState:(web::WebState*)webState {
   self.isDownloadCanceled = NO;
-  NSString* tempDirPath = [NSTemporaryDirectory()
-      stringByAppendingPathComponent:kDocumentsTemporaryPath];
+  NSString* tempDirPath = GetTemporaryDocumentDirectory();
   OpenInTabHelper* helper = OpenInTabHelper::FromWebState(webState);
   self.filePath = [tempDirPath
       stringByAppendingPathComponent:base::SysUTF16ToNSString(
@@ -290,6 +353,10 @@
 // Shows an overlayed spinner on the top view to indicate that a file download
 // is in progress.
 - (void)startDisplayDownloadOverlayOnWebView:(web::WebState*)currentWebState {
+  self.dispatcher = self.browser->GetCommandDispatcher();
+  [self.dispatcher
+      startDispatchingToTarget:self
+                   forProtocol:@protocol(ShareDownloadOverlayCommands)];
   self.overlay = [[ShareDownloadOverlayCoordinator alloc]
       initWithBaseViewController:self.baseViewController
                          browser:self.browser
@@ -301,6 +368,7 @@
 - (void)stopDisplayDownloadOverlay {
   [self.overlay stop];
   self.overlay = nil;
+  [self.dispatcher stopDispatchingToTarget:self];
 }
 
 // Removes downloaded file at `self.filePath`.
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_detail_text_item.mm b/ios/chrome/browser/ui/table_view/cells/table_view_detail_text_item.mm
index d3153ec3..8abddf2 100644
--- a/ios/chrome/browser/ui/table_view/cells/table_view_detail_text_item.mm
+++ b/ios/chrome/browser/ui/table_view/cells/table_view_detail_text_item.mm
@@ -80,7 +80,7 @@
     case TableViewDetailTextCellAccessorySymbolExternalLink:
       cell.accessoryView = [[UIImageView alloc]
           initWithImage:DefaultSymbolTemplateWithPointSize(
-                            kExternalLinkSmbol, kSymbolAccessoryPointSize)];
+                            kExternalLinkSymbol, kSymbolAccessoryPointSize)];
       break;
     case TableViewDetailTextCellAccessorySymbolNone:
       cell.accessoryView = nil;
diff --git a/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.mm b/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.mm
index 8dca851..f1a64be 100644
--- a/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.mm
+++ b/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.mm
@@ -31,10 +31,6 @@
 // The size of the symbol image.
 const CGFloat kSymbolToolbarPointSize = 24;
 
-// Specific symbols used in the toolbar.
-NSString* const kToolbarArrowBackwardSymbol = @"arrow.backward";
-NSString* const kToolbarArrowForwardSymbol = @"arrow.forward";
-
 }  // namespace
 
 @implementation ToolbarButtonFactory
@@ -52,10 +48,9 @@
 
 - (ToolbarButton*)backButton {
   UIImage* backImage;
-  backImage = UseSymbols()
-                  ? DefaultSymbolWithPointSize(kToolbarArrowBackwardSymbol,
-                                               kSymbolToolbarPointSize)
-                  : [UIImage imageNamed:@"toolbar_back"];
+  backImage = UseSymbols() ? DefaultSymbolWithPointSize(kBackSymbol,
+                                                        kSymbolToolbarPointSize)
+                           : [UIImage imageNamed:@"toolbar_back"];
   ToolbarButton* backButton = [ToolbarButton
       toolbarButtonWithImage:[backImage
                                  imageFlippedForRightToLeftLayoutDirection]];
@@ -71,9 +66,9 @@
 // Returns a forward button without visibility mask configured.
 - (ToolbarButton*)forwardButton {
   UIImage* forwardImage =
-      UseSymbols() ? DefaultSymbolWithPointSize(kToolbarArrowForwardSymbol,
-                                                kSymbolToolbarPointSize)
-                   : [UIImage imageNamed:@"toolbar_forward"];
+      UseSymbols()
+          ? DefaultSymbolWithPointSize(kForwardSymbol, kSymbolToolbarPointSize)
+          : [UIImage imageNamed:@"toolbar_forward"];
   ToolbarButton* forwardButton = [ToolbarButton
       toolbarButtonWithImage:[forwardImage
                                  imageFlippedForRightToLeftLayoutDirection]];
diff --git a/ios/chrome/common/ui/promo_style/promo_style_view_controller.mm b/ios/chrome/common/ui/promo_style/promo_style_view_controller.mm
index c73a8936..e75015d4 100644
--- a/ios/chrome/common/ui/promo_style/promo_style_view_controller.mm
+++ b/ios/chrome/common/ui/promo_style/promo_style_view_controller.mm
@@ -531,7 +531,7 @@
   }
 }
 
-- (void)setavatarAccessibilityLabel:(NSString*)avatarAccessibilityLabel {
+- (void)setAvatarAccessibilityLabel:(NSString*)avatarAccessibilityLabel {
   _avatarAccessibilityLabel = avatarAccessibilityLabel;
   if (self.hasAvatarImage) {
     self.avatarImageView.accessibilityLabel = avatarAccessibilityLabel;
diff --git a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
index cbd5ee0a..d6d7a37 100644
--- a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
+++ b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@
-a3fe971fb0733e846a567add87aba4effe81ae53
\ No newline at end of file
+f38a8f003eaa0529f41c39ef89992f8a874b0a5a
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
index 3b4d393a..e3118dc2 100644
--- a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
+++ b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@
-6483fbb724f291ee997db8c3a17d65f33edd050c
\ No newline at end of file
+846fcf651d96e06dd692197a51338f437522041f
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
index c750546..34595f3 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-0df38fcb9de73a1be2b04756158e87173658f829
\ No newline at end of file
+5dc796d6d88214d693783958cfd90457d2c33537
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
index cb715f71..7961104 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-ab2b4c851b30d539feaaa81c5f5ea44cd6526263
\ No newline at end of file
+1e256610365ffceafca6385c42989ecba29fedf9
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
index ba70ec8..916d0790 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-e2e06bc716faaf5b773255ceea05a6df51bb569e
\ No newline at end of file
+30f9c067d2c5dd7f11772ad87fa1b30ded294d06
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
index 3e36841..649cb4a 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-4e3150fb6d2888b44b912382a61e40ad46161e05
\ No newline at end of file
+b7384d271dd061cc697f0d55d3cea95b80fec4c0
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
index 3fa957f..21dc00d 100644
--- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-29b8cb97eb775ab021d77115376e2c1c664665d6
\ No newline at end of file
+14d12c8e80190e266070271f6b067925f5ee1896
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
index 3b4de13..d74c544d 100644
--- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-75457c235f2251c89754087bb3ded0c82100f85f
\ No newline at end of file
+69426fb5336094108a04cc3714fae485a452ec61
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
index 5eb9d91..87a5f445 100644
--- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-535aee9cf5fdc02991b20d4e2bd7ba11f2bc0d98
\ No newline at end of file
+9fb7c1cb99135f5f817ea19eed8b37491748a4dd
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
index 123c88d..bdfb0c5 100644
--- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-52f4eb12bc6561895ff0d8d4faab31c29fbb5df8
\ No newline at end of file
+0ae74e40ec78feca8dba9f62f5b177369e3d10b2
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
index 5e3fd7d..f743f2a5 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-d2d620f0c1adb7e1e5362ddb3ad764ec7e5d3ffe
\ No newline at end of file
+2aad958e79bef7e091169afdd3a837fc4115a645
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
index 3e3534a0..86782d2c 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-34d3ba77cfec53cc78d50970dad20c52a299f625
\ No newline at end of file
+61b225b35ea1ce3772e2fd82936bc093e60d5f3d
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
index d0281e9..27e0857 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-1eb00450bff0317a7325a53cdbb0da83926a2639
\ No newline at end of file
+2931b4faf0b5afc67e39230ccfb314b15d1bcd49
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
index 795b4458..0bb59d5 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-12757247afceccf0e0462dfe837416603f9b2d59
\ No newline at end of file
+6fe36274fb2afce6699109377148f8d3c628ef98
\ No newline at end of file
diff --git a/ios/web/annotations/resources/annotations.ts b/ios/web/annotations/resources/annotations.ts
index 49dd902..60b1d6b 100644
--- a/ios/web/annotations/resources/annotations.ts
+++ b/ios/web/annotations/resources/annotations.ts
@@ -120,7 +120,7 @@
  */
 type EnumNodesFunction = (node: Node, index: number, text: string) => boolean;
 
-let decorations: Decoration[];
+let decorations: Decoration[] = [];
 
 let sections: Section[];
 
@@ -145,7 +145,7 @@
  */
 function decorateAnnotations(annotations: Annotation[]): void {
   // Avoid redoing without going through `removeDecorations` first.
-  if (decorations?.length || !annotations.length)
+  if (decorations.length || !annotations.length)
     return;
 
   let failures = 0;
diff --git a/media/audio/null_audio_sink.cc b/media/audio/null_audio_sink.cc
index 337ce19..7baf2086 100644
--- a/media/audio/null_audio_sink.cc
+++ b/media/audio/null_audio_sink.cc
@@ -16,7 +16,7 @@
 namespace media {
 
 NullAudioSink::NullAudioSink(
-    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
+    const scoped_refptr<base::SequencedTaskRunner>& task_runner)
     : initialized_(false),
       started_(false),
       playing_(false),
@@ -36,14 +36,14 @@
 }
 
 void NullAudioSink::Start() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(initialized_);
   DCHECK(!started_);
   started_ = true;
 }
 
 void NullAudioSink::Stop() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   started_ = false;
   // Stop may be called at any time, so we have to check before stopping.
   if (fake_worker_)
@@ -51,7 +51,7 @@
 }
 
 void NullAudioSink::Play() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(started_);
 
   if (playing_)
@@ -64,7 +64,7 @@
 }
 
 void NullAudioSink::Pause() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(started_);
 
   if (!playing_)
@@ -95,7 +95,7 @@
 }
 
 bool NullAudioSink::CurrentThreadIsRenderingThread() {
-  return task_runner_->BelongsToCurrentThread();
+  return task_runner_->RunsTasksInCurrentSequence();
 }
 
 void NullAudioSink::SwitchOutputDevice(const std::string& device_id,
@@ -105,7 +105,7 @@
 
 void NullAudioSink::CallRender(base::TimeTicks ideal_time,
                                base::TimeTicks now) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   // Since NullAudioSink is only used for cases where a real audio sink was not
   // available, provide "idealized" delay-timing arguments. This will drive the
diff --git a/media/audio/null_audio_sink.h b/media/audio/null_audio_sink.h
index dd037a3..5a950a1 100644
--- a/media/audio/null_audio_sink.h
+++ b/media/audio/null_audio_sink.h
@@ -9,13 +9,10 @@
 #include <string>
 
 #include "base/memory/raw_ptr.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/time/time.h"
 #include "media/base/audio_renderer_sink.h"
 
-namespace base {
-class SingleThreadTaskRunner;
-}
-
 namespace media {
 class AudioBus;
 class AudioHash;
@@ -24,7 +21,7 @@
 class MEDIA_EXPORT NullAudioSink : public SwitchableAudioRendererSink {
  public:
   explicit NullAudioSink(
-      const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);
+      const scoped_refptr<base::SequencedTaskRunner>& task_runner);
 
   NullAudioSink(const NullAudioSink&) = delete;
   NullAudioSink& operator=(const NullAudioSink&) = delete;
@@ -66,7 +63,7 @@
   // Controls whether or not a running hash is computed for audio frames.
   std::unique_ptr<AudioHash> audio_hash_;
 
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+  scoped_refptr<base::SequencedTaskRunner> task_runner_;
   std::unique_ptr<FakeAudioWorker> fake_worker_;
   base::TimeDelta fixed_data_delay_;
   std::unique_ptr<AudioBus> audio_bus_;
diff --git a/media/base/fake_audio_worker.cc b/media/base/fake_audio_worker.cc
index 291c2f82..000a5e0 100644
--- a/media/base/fake_audio_worker.cc
+++ b/media/base/fake_audio_worker.cc
@@ -12,6 +12,7 @@
 #include "base/check_op.h"
 #include "base/location.h"
 #include "base/synchronization/lock.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/thread_annotations.h"
 #include "base/threading/thread_checker.h"
@@ -24,7 +25,7 @@
 class FakeAudioWorker::Worker
     : public base::RefCountedThreadSafe<FakeAudioWorker::Worker> {
  public:
-  Worker(const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner,
+  Worker(const scoped_refptr<base::SequencedTaskRunner>& worker_task_runner,
          const AudioParameters& params);
 
   Worker(const Worker&) = delete;
@@ -49,7 +50,7 @@
   // the worker loop.
   void DoRead();
 
-  const scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner_;
+  const scoped_refptr<base::SequencedTaskRunner> worker_task_runner_;
   const int sample_rate_;
   const int frames_per_read_;
 
@@ -61,11 +62,11 @@
   // Used to cancel any delayed tasks still inside the worker loop's queue.
   base::CancelableRepeatingClosure worker_task_cb_;
 
-  THREAD_CHECKER(thread_checker_);
+  SEQUENCE_CHECKER(sequence_checker_);
 };
 
 FakeAudioWorker::FakeAudioWorker(
-    const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& worker_task_runner,
     const AudioParameters& params)
     : worker_(new Worker(worker_task_runner, params)) {}
 
@@ -94,14 +95,14 @@
 }
 
 FakeAudioWorker::Worker::Worker(
-    const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& worker_task_runner,
     const AudioParameters& params)
     : worker_task_runner_(worker_task_runner),
       sample_rate_(params.sample_rate()),
       frames_per_read_(params.frames_per_buffer()) {
   // Worker can be constructed on any thread, but will DCHECK that its
   // Start/Stop methods are called from the same thread.
-  DETACH_FROM_THREAD(thread_checker_);
+  DETACH_FROM_SEQUENCE(sequence_checker_);
 }
 
 FakeAudioWorker::Worker::~Worker() {
@@ -114,7 +115,7 @@
 }
 
 void FakeAudioWorker::Worker::Start(FakeAudioWorker::Callback worker_cb) {
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(worker_cb);
   {
     base::AutoLock scoped_lock(worker_cb_lock_);
@@ -126,7 +127,7 @@
 }
 
 void FakeAudioWorker::Worker::DoStart() {
-  DCHECK(worker_task_runner_->BelongsToCurrentThread());
+  DCHECK(worker_task_runner_->RunsTasksInCurrentSequence());
   first_read_time_ = base::TimeTicks::Now();
   frames_elapsed_ = 0;
   worker_task_cb_.Reset(base::BindRepeating(&Worker::DoRead, this));
@@ -134,7 +135,7 @@
 }
 
 void FakeAudioWorker::Worker::Stop() {
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   {
     base::AutoLock scoped_lock(worker_cb_lock_);
     if (!worker_cb_)
@@ -146,12 +147,12 @@
 }
 
 void FakeAudioWorker::Worker::DoCancel() {
-  DCHECK(worker_task_runner_->BelongsToCurrentThread());
+  DCHECK(worker_task_runner_->RunsTasksInCurrentSequence());
   worker_task_cb_.Cancel();
 }
 
 void FakeAudioWorker::Worker::DoRead() {
-  DCHECK(worker_task_runner_->BelongsToCurrentThread());
+  DCHECK(worker_task_runner_->RunsTasksInCurrentSequence());
 
   const base::TimeTicks read_time =
       first_read_time_ +
diff --git a/media/base/fake_audio_worker.h b/media/base/fake_audio_worker.h
index 097bc0b2..23ba43d 100644
--- a/media/base/fake_audio_worker.h
+++ b/media/base/fake_audio_worker.h
@@ -7,13 +7,13 @@
 
 #include "base/callback_forward.h"
 #include "base/memory/ref_counted.h"
+#include "base/task/sequenced_task_runner.h"
 #include "media/base/media_export.h"
 
 namespace base {
-class SingleThreadTaskRunner;
 class TimeDelta;
 class TimeTicks;
-}
+}  // namespace base
 
 namespace media {
 class AudioParameters;
@@ -33,7 +33,7 @@
   // thread that invokes the Start/Stop methods.
   // |params| is used to determine the frequency of callbacks.
   FakeAudioWorker(
-      const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner,
+      const scoped_refptr<base::SequencedTaskRunner>& worker_task_runner,
       const AudioParameters& params);
 
   FakeAudioWorker(const FakeAudioWorker&) = delete;
diff --git a/media/base/media_url_demuxer.cc b/media/base/media_url_demuxer.cc
index 180887a19..5b3a58025 100644
--- a/media/base/media_url_demuxer.cc
+++ b/media/base/media_url_demuxer.cc
@@ -11,7 +11,7 @@
 namespace media {
 
 MediaUrlDemuxer::MediaUrlDemuxer(
-    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& task_runner,
     const GURL& media_url,
     const net::SiteForCookies& site_for_cookies,
     const url::Origin& top_frame_origin,
@@ -44,7 +44,7 @@
 void MediaUrlDemuxer::ForwardDurationChangeToDemuxerHost(
     base::TimeDelta duration) {
   DCHECK(host_);
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   host_->SetDuration(duration);
 }
 
diff --git a/media/base/media_url_demuxer.h b/media/base/media_url_demuxer.h
index f4c721a..1be5a29 100644
--- a/media/base/media_url_demuxer.h
+++ b/media/base/media_url_demuxer.h
@@ -13,10 +13,6 @@
 #include "media/base/demuxer.h"
 #include "url/gurl.h"
 
-namespace base {
-class SingleThreadTaskRunner;
-}  // namespace base
-
 namespace net {
 class SiteForCookies;
 }  // namespace net
@@ -36,13 +32,12 @@
 // MediaResource.
 class MEDIA_EXPORT MediaUrlDemuxer : public Demuxer {
  public:
-  MediaUrlDemuxer(
-      const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
-      const GURL& media_url,
-      const net::SiteForCookies& site_for_cookies,
-      const url::Origin& top_frame_origin,
-      bool allow_credentials,
-      bool is_hls);
+  MediaUrlDemuxer(const scoped_refptr<base::SequencedTaskRunner>& task_runner,
+                  const GURL& media_url,
+                  const net::SiteForCookies& site_for_cookies,
+                  const url::Origin& top_frame_origin,
+                  bool allow_credentials,
+                  bool is_hls);
 
   MediaUrlDemuxer(const MediaUrlDemuxer&) = delete;
   MediaUrlDemuxer& operator=(const MediaUrlDemuxer&) = delete;
@@ -79,7 +74,7 @@
   MediaUrlParams params_;
   raw_ptr<DemuxerHost> host_;
 
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+  scoped_refptr<base::SequencedTaskRunner> task_runner_;
 };
 
 }  // namespace media
diff --git a/media/base/memory_dump_provider_proxy.cc b/media/base/memory_dump_provider_proxy.cc
index 8dcde76..e8b3b2b 100644
--- a/media/base/memory_dump_provider_proxy.cc
+++ b/media/base/memory_dump_provider_proxy.cc
@@ -12,11 +12,12 @@
 
 MemoryDumpProviderProxy::MemoryDumpProviderProxy(
     const char* name,
-    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    scoped_refptr<base::SequencedTaskRunner> task_runner,
     MemoryDumpCB dump_cb)
     : dump_cb_(std::move(dump_cb)) {
-  base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-      this, name, std::move(task_runner));
+  base::trace_event::MemoryDumpManager::GetInstance()
+      ->RegisterDumpProviderWithSequencedTaskRunner(
+          this, name, std::move(task_runner), MemoryDumpProvider::Options());
 }
 
 MemoryDumpProviderProxy::~MemoryDumpProviderProxy() {
diff --git a/media/base/memory_dump_provider_proxy.h b/media/base/memory_dump_provider_proxy.h
index fa418aa..c67a09e 100644
--- a/media/base/memory_dump_provider_proxy.h
+++ b/media/base/memory_dump_provider_proxy.h
@@ -10,6 +10,7 @@
 
 #include "base/memory/ref_counted.h"
 #include "base/strings/string_piece.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/trace_event/memory_dump_provider.h"
 #include "media/base/media_export.h"
@@ -23,10 +24,9 @@
 class MEDIA_EXPORT MemoryDumpProviderProxy final
     : public base::trace_event::MemoryDumpProvider {
  public:
-  MemoryDumpProviderProxy(
-      const char* name,
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
-      MemoryDumpCB dump_cb);
+  MemoryDumpProviderProxy(const char* name,
+                          scoped_refptr<base::SequencedTaskRunner> task_runner,
+                          MemoryDumpCB dump_cb);
 
   MemoryDumpProviderProxy(const MemoryDumpProviderProxy&) = delete;
   MemoryDumpProviderProxy& operator=(const MemoryDumpProviderProxy&) = delete;
diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h
index e2b22f02..63ea945 100644
--- a/media/base/mock_filters.h
+++ b/media/base/mock_filters.h
@@ -534,14 +534,14 @@
   ~MockRendererFactory() override;
 
   // Renderer implementation.
-  MOCK_METHOD6(CreateRenderer,
-               std::unique_ptr<Renderer>(
-                   const scoped_refptr<base::SingleThreadTaskRunner>&,
-                   const scoped_refptr<base::TaskRunner>&,
-                   AudioRendererSink*,
-                   VideoRendererSink*,
-                   RequestOverlayInfoCB,
-                   const gfx::ColorSpace&));
+  MOCK_METHOD6(
+      CreateRenderer,
+      std::unique_ptr<Renderer>(const scoped_refptr<base::SequencedTaskRunner>&,
+                                const scoped_refptr<base::TaskRunner>&,
+                                AudioRendererSink*,
+                                VideoRendererSink*,
+                                RequestOverlayInfoCB,
+                                const gfx::ColorSpace&));
 };
 
 class MockTimeSource : public TimeSource {
diff --git a/media/base/pipeline_impl.cc b/media/base/pipeline_impl.cc
index 4f79aa74..7070e27 100644
--- a/media/base/pipeline_impl.cc
+++ b/media/base/pipeline_impl.cc
@@ -18,6 +18,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/synchronization/lock.h"
 #include "base/synchronization/waitable_event.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
@@ -61,7 +62,7 @@
 class PipelineImpl::RendererWrapper final : public DemuxerHost,
                                             public RendererClient {
  public:
-  RendererWrapper(scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+  RendererWrapper(scoped_refptr<base::SequencedTaskRunner> media_task_runner,
                   scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
                   MediaLog* media_log);
 
@@ -190,7 +191,7 @@
   // one by calling back to PipelineImpl. Fires |done_cb| with the result.
   void CreateRendererInternal(PipelineStatusCallback done_cb);
 
-  const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+  const scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
   const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
   const raw_ptr<MediaLog> media_log_;
 
@@ -248,7 +249,7 @@
 };
 
 PipelineImpl::RendererWrapper::RendererWrapper(
-    scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+    scoped_refptr<base::SequencedTaskRunner> media_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
     MediaLog* media_log)
     : media_task_runner_(std::move(media_task_runner)),
@@ -264,7 +265,7 @@
       text_renderer_ended_(false) {}
 
 PipelineImpl::RendererWrapper::~RendererWrapper() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(state_ == kCreated || state_ == kStopped);
 }
 
@@ -279,7 +280,7 @@
     Demuxer* demuxer,
     std::unique_ptr<Renderer> default_renderer,
     base::WeakPtr<PipelineImpl> weak_pipeline) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(state_ == kCreated || state_ == kStopped)
       << "Received start in unexpected state: " << state_;
   DCHECK(!demuxer_);
@@ -325,7 +326,7 @@
 }
 
 void PipelineImpl::RendererWrapper::Stop() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(state_ != kStopping && state_ != kStopped);
 
   SetState(kStopping);
@@ -357,7 +358,7 @@
 }
 
 void PipelineImpl::RendererWrapper::Seek(base::TimeDelta time) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   // Suppress seeking if we're not fully started.
   if (state_ != kPlaying) {
@@ -398,7 +399,7 @@
 }
 
 void PipelineImpl::RendererWrapper::Suspend() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   // Suppress suspending if we're not playing.
   if (state_ != kPlaying) {
@@ -432,7 +433,7 @@
 void PipelineImpl::RendererWrapper::Resume(
     std::unique_ptr<Renderer> default_renderer,
     base::TimeDelta timestamp) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   // Suppress resuming if we're not suspended.
   if (state_ != kSuspended) {
@@ -475,7 +476,7 @@
 }
 
 void PipelineImpl::RendererWrapper::SetPlaybackRate(double playback_rate) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   playback_rate_ = playback_rate;
   if (state_ == kPlaying)
@@ -483,7 +484,7 @@
 }
 
 void PipelineImpl::RendererWrapper::SetVolume(float volume) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   volume_ = volume;
   if (shared_state_.renderer)
@@ -492,7 +493,7 @@
 
 void PipelineImpl::RendererWrapper::SetLatencyHint(
     absl::optional<base::TimeDelta> latency_hint) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   if (latency_hint_ == latency_hint)
     return;
@@ -503,7 +504,7 @@
 }
 
 void PipelineImpl::RendererWrapper::SetPreservesPitch(bool preserves_pitch) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   if (preserves_pitch_ == preserves_pitch)
     return;
@@ -515,7 +516,7 @@
 
 void PipelineImpl::RendererWrapper::SetWasPlayedWithUserActivation(
     bool was_played_with_user_activation) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   was_played_with_user_activation_ = was_played_with_user_activation;
   if (shared_state_.renderer) {
@@ -560,7 +561,7 @@
 
 void PipelineImpl::RendererWrapper::SetCdm(CdmContext* cdm_context,
                                            CdmAttachedCB cdm_attached_cb) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(cdm_context);
 
   // If there's already a renderer, set the CDM on the renderer directly.
@@ -651,20 +652,20 @@
 }
 
 void PipelineImpl::RendererWrapper::OnError(PipelineStatus error) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(error_cb_);
   media_task_runner_->PostTask(FROM_HERE, base::BindOnce(error_cb_, error));
 }
 
 void PipelineImpl::RendererWrapper::OnFallback(PipelineStatus fallback) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   main_task_runner_->PostTask(
       FROM_HERE, base::BindOnce(&PipelineImpl::OnFallback, weak_pipeline_,
                                 std::move(fallback).AddHere()));
 }
 
 void PipelineImpl::RendererWrapper::OnEnded() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   media_log_->AddEvent<MediaLogEvent::kEnded>();
 
   if (state_ != kPlaying)
@@ -677,7 +678,7 @@
 
 // TODO(crbug/817089): Combine this functionality into renderer->GetMediaTime().
 base::TimeDelta PipelineImpl::RendererWrapper::GetCurrentTimestamp() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(demuxer_);
   DCHECK(shared_state_.renderer || state_ != kPlaying);
 
@@ -700,7 +701,7 @@
 void PipelineImpl::RendererWrapper::OnEnabledAudioTracksChanged(
     const std::vector<MediaTrack::Id>& enabled_track_ids,
     base::OnceClosure change_completed_cb) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   // If the pipeline has been created, but not started yet, we may still receive
   // track notifications from blink level (e.g. when video track gets deselected
@@ -741,7 +742,7 @@
 void PipelineImpl::RendererWrapper::OnSelectedVideoTrackChanged(
     absl::optional<MediaTrack::Id> selected_track_id,
     base::OnceClosure change_completed_cb) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   // See RenderWrapper::OnEnabledAudioTracksChanged.
   if (state_ == kCreated) {
@@ -779,7 +780,7 @@
 }
 
 void PipelineImpl::RendererWrapper::OnExternalVideoFrameRequest() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   if (!shared_state_.renderer) {
     return;
   }
@@ -791,7 +792,7 @@
     base::OnceClosure change_completed_cb,
     DemuxerStream::Type stream_type,
     const std::vector<DemuxerStream*>& streams) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   if (!shared_state_.renderer) {
     // This can happen if the pipeline has been suspended.
     std::move(change_completed_cb).Run();
@@ -817,7 +818,7 @@
 void PipelineImpl::RendererWrapper::OnStatisticsUpdate(
     const PipelineStatistics& stats) {
   DVLOG(3) << __func__;
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   base::AutoLock auto_lock(shared_state_lock_);
   shared_state_.statistics.audio_bytes_decoded += stats.audio_bytes_decoded;
@@ -871,7 +872,7 @@
 void PipelineImpl::RendererWrapper::OnBufferingStateChange(
     BufferingState state,
     BufferingStateChangeReason reason) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DVLOG(2) << __func__ << "(" << state << ", " << reason << ") ";
 
   main_task_runner_->PostTask(
@@ -880,7 +881,7 @@
 }
 
 void PipelineImpl::RendererWrapper::OnWaiting(WaitingReason reason) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   main_task_runner_->PostTask(
       FROM_HERE,
@@ -889,7 +890,7 @@
 
 void PipelineImpl::RendererWrapper::OnVideoNaturalSizeChange(
     const gfx::Size& size) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   main_task_runner_->PostTask(
       FROM_HERE, base::BindOnce(&PipelineImpl::OnVideoNaturalSizeChange,
@@ -897,7 +898,7 @@
 }
 
 void PipelineImpl::RendererWrapper::OnVideoOpacityChange(bool opaque) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   main_task_runner_->PostTask(
       FROM_HERE, base::BindOnce(&PipelineImpl::OnVideoOpacityChange,
@@ -906,7 +907,7 @@
 
 void PipelineImpl::RendererWrapper::OnVideoFrameRateChange(
     absl::optional<int> fps) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   main_task_runner_->PostTask(
       FROM_HERE, base::BindOnce(&PipelineImpl::OnVideoFrameRateChange,
@@ -915,7 +916,7 @@
 
 void PipelineImpl::RendererWrapper::OnAudioConfigChange(
     const AudioDecoderConfig& config) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   main_task_runner_->PostTask(FROM_HERE,
                               base::BindOnce(&PipelineImpl::OnAudioConfigChange,
@@ -924,7 +925,7 @@
 
 void PipelineImpl::RendererWrapper::OnVideoConfigChange(
     const VideoDecoderConfig& config) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   main_task_runner_->PostTask(FROM_HERE,
                               base::BindOnce(&PipelineImpl::OnVideoConfigChange,
@@ -932,7 +933,7 @@
 }
 
 void PipelineImpl::RendererWrapper::OnPipelineError(PipelineStatus error) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(!error.is_ok()) << "PIPELINE_OK isn't an error!";
 
   // Preserve existing abnormal status.
@@ -956,7 +957,7 @@
 void PipelineImpl::RendererWrapper::OnCdmAttached(CdmAttachedCB cdm_attached_cb,
                                                   CdmContext* cdm_context,
                                                   bool success) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   if (success)
     cdm_context_ = cdm_context;
@@ -964,7 +965,7 @@
 }
 
 void PipelineImpl::RendererWrapper::CheckPlaybackEnded() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   if (shared_state_.renderer && !renderer_ended_)
     return;
@@ -978,7 +979,7 @@
 }
 
 void PipelineImpl::RendererWrapper::SetState(State next_state) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DVLOG(1) << PipelineImpl::GetStateString(state_) << " -> "
            << PipelineImpl::GetStateString(next_state);
 
@@ -993,7 +994,7 @@
 void PipelineImpl::RendererWrapper::CompleteSeek(base::TimeDelta seek_time,
                                                  PipelineStatus status) {
   DVLOG(1) << __func__ << ": seek_time=" << seek_time << ", status=" << status;
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(state_ == kStarting || state_ == kSeeking || state_ == kResuming);
 
   if (state_ == kStarting) {
@@ -1026,7 +1027,7 @@
 
 void PipelineImpl::RendererWrapper::CompleteSuspend(PipelineStatus status) {
   DVLOG(1) << __func__ << ": status=" << status;
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK_EQ(kSuspending, state_);
 
   DCHECK(pending_callbacks_);
@@ -1055,7 +1056,7 @@
 
 void PipelineImpl::RendererWrapper::InitializeDemuxer(
     PipelineStatusCallback done_cb) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   demuxer_->Initialize(this, std::move(done_cb));
 }
@@ -1063,7 +1064,7 @@
 void PipelineImpl::RendererWrapper::CreateRenderer(
     PipelineStatusCallback done_cb) {
   DVLOG(1) << __func__;
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(state_ == kStarting || state_ == kResuming);
 
   if (HasEncryptedStream() && !cdm_context_) {
@@ -1080,7 +1081,7 @@
     PipelineStatusCallback done_cb,
     std::unique_ptr<Renderer> renderer) {
   DVLOG(1) << __func__ << ": renderer=" << renderer.get();
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   if (!renderer) {
     std::move(done_cb).Run(PIPELINE_ERROR_INITIALIZATION_FAILED);
@@ -1098,7 +1099,7 @@
 void PipelineImpl::RendererWrapper::InitializeRenderer(
     PipelineStatusCallback done_cb) {
   DVLOG(1) << __func__;
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   switch (demuxer_->GetType()) {
     case MediaResource::Type::STREAM:
@@ -1138,7 +1139,7 @@
 }
 
 void PipelineImpl::RendererWrapper::DestroyRenderer() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   // Destroy the renderer outside the lock scope to avoid holding the lock
   // while renderer is being destroyed (in case Renderer destructor is costly).
@@ -1150,7 +1151,7 @@
 }
 
 void PipelineImpl::RendererWrapper::ReportMetadata(StartType start_type) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   PipelineMetadata metadata;
   std::vector<DemuxerStream*> streams;
@@ -1226,7 +1227,7 @@
 }
 
 PipelineImpl::PipelineImpl(
-    scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+    scoped_refptr<base::SequencedTaskRunner> media_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
     CreateRendererCB create_renderer_cb,
     MediaLog* media_log)
@@ -1300,7 +1301,7 @@
     return;
   }
 
-  if (media_task_runner_->BelongsToCurrentThread()) {
+  if (media_task_runner_->RunsTasksInCurrentSequence()) {
     // This path is executed by unittests that share media and main threads.
     renderer_wrapper_->Stop();
   } else {
diff --git a/media/base/pipeline_impl.h b/media/base/pipeline_impl.h
index 04d1fa6..61144d0 100644
--- a/media/base/pipeline_impl.h
+++ b/media/base/pipeline_impl.h
@@ -10,6 +10,7 @@
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/threading/thread_checker.h"
 #include "base/time/time.h"
 #include "media/base/media_export.h"
@@ -83,7 +84,7 @@
  public:
   // Constructs a pipeline that will execute media tasks on |media_task_runner|.
   // |create_renderer_cb|: to create renderers when starting and resuming.
-  PipelineImpl(scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+  PipelineImpl(scoped_refptr<base::SequencedTaskRunner> media_task_runner,
                scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
                CreateRendererCB create_renderer_cb,
                MediaLog* media_log);
@@ -181,7 +182,7 @@
   void OnSuspendDone();
 
   // Parameters passed in the constructor.
-  const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+  const scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
   CreateRendererCB create_renderer_cb_;
   const raw_ptr<MediaLog> media_log_;
 
diff --git a/media/base/renderer_factory.h b/media/base/renderer_factory.h
index c3b417e4..c18e11f 100644
--- a/media/base/renderer_factory.h
+++ b/media/base/renderer_factory.h
@@ -8,6 +8,7 @@
 #include <memory>
 
 #include "base/memory/ref_counted.h"
+#include "base/task/sequenced_task_runner.h"
 #include "media/base/media_export.h"
 #include "media/base/media_resource.h"
 #include "media/base/overlay_info.h"
@@ -15,7 +16,6 @@
 #include "ui/gfx/color_space.h"
 
 namespace base {
-class SingleThreadTaskRunner;
 class TaskRunner;
 }
 
@@ -40,7 +40,7 @@
   // The created Renderer can use |audio_renderer_sink| to render audio and
   // |video_renderer_sink| to render video.
   virtual std::unique_ptr<Renderer> CreateRenderer(
-      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+      const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
       const scoped_refptr<base::TaskRunner>& worker_task_runner,
       AudioRendererSink* audio_renderer_sink,
       VideoRendererSink* video_renderer_sink,
diff --git a/media/base/renderer_factory_selector_unittest.cc b/media/base/renderer_factory_selector_unittest.cc
index 31b113b..fa30f76c0 100644
--- a/media/base/renderer_factory_selector_unittest.cc
+++ b/media/base/renderer_factory_selector_unittest.cc
@@ -18,7 +18,7 @@
     explicit FakeFactory(RendererType type) : type_(type) {}
 
     std::unique_ptr<Renderer> CreateRenderer(
-        const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+        const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
         const scoped_refptr<base::TaskRunner>& worker_task_runner,
         AudioRendererSink* audio_renderer_sink,
         VideoRendererSink* video_renderer_sink,
diff --git a/media/base/serial_runner.cc b/media/base/serial_runner.cc
index d43a34e..376afbc 100644
--- a/media/base/serial_runner.cc
+++ b/media/base/serial_runner.cc
@@ -8,6 +8,7 @@
 #include "base/callback_helpers.h"
 #include "base/location.h"
 #include "base/task/single_thread_task_runner.h"
+#include "base/threading/sequenced_task_runner_handle.h"
 #include "base/threading/thread_task_runner_handle.h"
 
 namespace media {
@@ -30,7 +31,7 @@
 
 // Runs |status_cb| with |last_status| on |task_runner|.
 static void RunOnTaskRunner(
-    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& task_runner,
     PipelineStatusCallback status_cb,
     PipelineStatus last_status) {
   // Force post to permit cancellation of a series in the scenario where all
@@ -67,7 +68,7 @@
 }
 
 SerialRunner::SerialRunner(Queue&& bound_fns, PipelineStatusCallback done_cb)
-    : task_runner_(base::ThreadTaskRunnerHandle::Get()),
+    : task_runner_(base::SequencedTaskRunnerHandle::Get()),
       bound_fns_(std::move(bound_fns)),
       done_cb_(std::move(done_cb)) {
   // Respect both cancellation and calling stack guarantees for |done_cb|
@@ -93,7 +94,7 @@
 }
 
 void SerialRunner::RunNextInSeries(PipelineStatus last_status) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(done_cb_);
 
   if (bound_fns_.empty() || last_status != PIPELINE_OK) {
diff --git a/media/base/serial_runner.h b/media/base/serial_runner.h
index 959816e..0cf3cefd 100644
--- a/media/base/serial_runner.h
+++ b/media/base/serial_runner.h
@@ -14,10 +14,6 @@
 #include "media/base/media_export.h"
 #include "media/base/pipeline_status.h"
 
-namespace base {
-class SingleThreadTaskRunner;
-}
-
 namespace media {
 
 // Runs a series of bound functions accepting Closures or
@@ -81,7 +77,7 @@
 
   void RunNextInSeries(PipelineStatus last_status);
 
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+  scoped_refptr<base::SequencedTaskRunner> task_runner_;
   Queue bound_fns_;
   PipelineStatusCallback done_cb_;
 
diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc
index 76661fc..af5a0fb 100644
--- a/media/filters/ffmpeg_demuxer.cc
+++ b/media/filters/ffmpeg_demuxer.cc
@@ -23,7 +23,7 @@
 #include "base/task/sequenced_task_runner.h"
 #include "base/task/task_runner_util.h"
 #include "base/task/thread_pool.h"
-#include "base/threading/thread_task_runner_handle.h"
+#include "base/threading/sequenced_task_runner_handle.h"
 #include "base/time/time.h"
 #include "base/trace_event/trace_event.h"
 #include "build/build_config.h"
@@ -260,7 +260,7 @@
     std::unique_ptr<VideoDecoderConfig> video_config,
     MediaLog* media_log)
     : demuxer_(demuxer),
-      task_runner_(base::ThreadTaskRunnerHandle::Get()),
+      task_runner_(base::SequencedTaskRunnerHandle::Get()),
       stream_(stream),
       start_time_(kNoTimestamp),
       audio_config_(audio_config.release()),
diff --git a/media/fuchsia/video/fuchsia_video_decoder_unittest.cc b/media/fuchsia/video/fuchsia_video_decoder_unittest.cc
index 8c77ad08..b3ac09c 100644
--- a/media/fuchsia/video/fuchsia_video_decoder_unittest.cc
+++ b/media/fuchsia/video/fuchsia_video_decoder_unittest.cc
@@ -231,7 +231,7 @@
   void Release() const override {
     base::RefCountedThreadSafe<TestRasterContextProvider>::Release();
   }
-  gpu::ContextResult BindToCurrentThread() override {
+  gpu::ContextResult BindToCurrentSequence() override {
     ADD_FAILURE();
     return gpu::ContextResult::kFatalFailure;
   }
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn
index 0ee3b89..5697fd99e 100644
--- a/media/gpu/BUILD.gn
+++ b/media/gpu/BUILD.gn
@@ -168,7 +168,6 @@
     libs += [ "android" ]
     deps += [
       ":mediacodec_stubs",
-      "//gpu/ipc/common:android_image_reader_utils",
 
       # TODO(crbug.com/789435): This can be removed once CdmManager is removed.
       "//gpu/ipc/common",
diff --git a/media/mojo/clients/mojo_renderer.cc b/media/mojo/clients/mojo_renderer.cc
index c529abc3..7eba4c8 100644
--- a/media/mojo/clients/mojo_renderer.cc
+++ b/media/mojo/clients/mojo_renderer.cc
@@ -22,7 +22,7 @@
 namespace media {
 
 MojoRenderer::MojoRenderer(
-    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& task_runner,
     std::unique_ptr<VideoOverlayFactory> video_overlay_factory,
     VideoRendererSink* video_renderer_sink,
     mojo::PendingRemote<mojom::Renderer> remote_renderer)
@@ -36,7 +36,7 @@
 
 MojoRenderer::~MojoRenderer() {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   CancelPendingCallbacks();
 }
@@ -45,7 +45,7 @@
                               media::RendererClient* client,
                               PipelineStatusCallback init_cb) {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(media_resource);
 
   if (encountered_error_) {
@@ -71,7 +71,7 @@
 void MojoRenderer::InitializeRendererFromStreams(
     media::RendererClient* client) {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   // Create mojom::DemuxerStream for each demuxer stream and bind its lifetime
   // to the pipe.
@@ -106,7 +106,7 @@
 
 void MojoRenderer::InitializeRendererFromUrl(media::RendererClient* client) {
   DVLOG(2) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   BindRemoteRendererIfNeeded();
 
@@ -128,7 +128,7 @@
 void MojoRenderer::SetCdm(CdmContext* cdm_context,
                           CdmAttachedCB cdm_attached_cb) {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(cdm_context);
   DCHECK(cdm_attached_cb);
   DCHECK(!cdm_attached_cb_);
@@ -162,7 +162,7 @@
 
 void MojoRenderer::Flush(base::OnceClosure flush_cb) {
   DVLOG(2) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(remote_renderer_.is_bound());
   DCHECK(flush_cb);
   DCHECK(!flush_cb_);
@@ -185,7 +185,7 @@
 
 void MojoRenderer::StartPlayingFrom(base::TimeDelta time) {
   DVLOG(2) << __func__ << "(" << time << ")";
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(remote_renderer_.is_bound());
 
   {
@@ -199,7 +199,7 @@
 
 void MojoRenderer::SetPlaybackRate(double playback_rate) {
   DVLOG(2) << __func__ << "(" << playback_rate << ")";
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(remote_renderer_.is_bound());
 
   remote_renderer_->SetPlaybackRate(playback_rate);
@@ -212,7 +212,7 @@
 
 void MojoRenderer::SetVolume(float volume) {
   DVLOG(2) << __func__ << "(" << volume << ")";
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   volume_ = volume;
   if (remote_renderer_.is_bound())
@@ -229,7 +229,7 @@
                                 base::TimeTicks capture_time) {
   DVLOG(4) << __func__ << "(" << time << ", " << max_time << ", "
            << capture_time << ")";
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   base::AutoLock auto_lock(lock_);
   media_time_interpolator_.SetBounds(time, max_time, capture_time);
@@ -238,19 +238,19 @@
 void MojoRenderer::OnBufferingStateChange(BufferingState state,
                                           BufferingStateChangeReason reason) {
   DVLOG(2) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   client_->OnBufferingStateChange(state, reason);
 }
 
 void MojoRenderer::OnEnded() {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   client_->OnEnded();
 }
 
 void MojoRenderer::OnError(const PipelineStatus& status) {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(!init_cb_);
 
   encountered_error_ = true;
@@ -259,7 +259,7 @@
 
 void MojoRenderer::OnVideoNaturalSizeChange(const gfx::Size& size) {
   DVLOG(2) << __func__ << ": " << size.ToString();
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   if (video_overlay_factory_) {
     video_renderer_sink_->PaintSingleFrame(
@@ -270,25 +270,25 @@
 
 void MojoRenderer::OnVideoOpacityChange(bool opaque) {
   DVLOG(2) << __func__ << ": " << opaque;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   client_->OnVideoOpacityChange(opaque);
 }
 
 void MojoRenderer::OnAudioConfigChange(const AudioDecoderConfig& config) {
   DVLOG(2) << __func__ << ": " << config.AsHumanReadableString();
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   client_->OnAudioConfigChange(config);
 }
 
 void MojoRenderer::OnVideoConfigChange(const VideoDecoderConfig& config) {
   DVLOG(2) << __func__ << ": " << config.AsHumanReadableString();
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   client_->OnVideoConfigChange(config);
 }
 
 void MojoRenderer::OnStatisticsUpdate(const PipelineStatistics& stats) {
   DVLOG(3) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   if (!client_) {
     pending_stats_ = stats;
     return;
@@ -298,13 +298,13 @@
 
 void MojoRenderer::OnWaiting(WaitingReason reason) {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   client_->OnWaiting(reason);
 }
 
 void MojoRenderer::OnConnectionError() {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   encountered_error_ = true;
   CancelPendingCallbacks();
@@ -316,7 +316,7 @@
 void MojoRenderer::OnDemuxerStreamConnectionError(
     MojoDemuxerStreamImpl* stream) {
   DVLOG(1) << __func__ << ": stream=" << stream;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   for (auto& s : streams_) {
     if (s.get() == stream) {
@@ -329,7 +329,7 @@
 
 void MojoRenderer::BindRemoteRendererIfNeeded() {
   DVLOG(2) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   // If |remote_renderer_| has already been bound, do nothing.
   // Note that after Bind() is called, |remote_renderer_| is always bound even
@@ -350,7 +350,7 @@
 
 void MojoRenderer::OnInitialized(media::RendererClient* client, bool success) {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(init_cb_);
 
   // Only set |client_| after initialization succeeded. No client methods should
@@ -373,7 +373,7 @@
 
 void MojoRenderer::OnFlushed() {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(flush_cb_);
 
   std::move(flush_cb_).Run();
@@ -381,7 +381,7 @@
 
 void MojoRenderer::OnCdmAttached(bool success) {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(cdm_attached_cb_);
 
   std::move(cdm_attached_cb_).Run(success);
@@ -389,7 +389,7 @@
 
 void MojoRenderer::CancelPendingCallbacks() {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   if (init_cb_)
     std::move(init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED);
diff --git a/media/mojo/clients/mojo_renderer.h b/media/mojo/clients/mojo_renderer.h
index 3e98c19..75ca4fd 100644
--- a/media/mojo/clients/mojo_renderer.h
+++ b/media/mojo/clients/mojo_renderer.h
@@ -22,10 +22,6 @@
 #include "mojo/public/cpp/bindings/remote.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
-namespace base {
-class SingleThreadTaskRunner;
-}
-
 namespace media {
 
 class MediaResource;
@@ -45,7 +41,7 @@
 // which can be called on any thread.
 class MojoRenderer : public Renderer, public mojom::RendererClient {
  public:
-  MojoRenderer(const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
+  MojoRenderer(const scoped_refptr<base::SequencedTaskRunner>& task_runner,
                std::unique_ptr<VideoOverlayFactory> video_overlay_factory,
                VideoRendererSink* video_renderer_sink,
                mojo::PendingRemote<mojom::Renderer> remote_renderer);
@@ -112,7 +108,7 @@
 
   // |task_runner| on which all methods are invoked, except for GetMediaTime(),
   // which can be called on any thread.
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+  scoped_refptr<base::SequencedTaskRunner> task_runner_;
 
   // Overlay factory used to create overlays for video frames rendered
   // by the remote renderer.
diff --git a/media/mojo/clients/mojo_renderer_factory.cc b/media/mojo/clients/mojo_renderer_factory.cc
index 443b787..cafc8ef 100644
--- a/media/mojo/clients/mojo_renderer_factory.cc
+++ b/media/mojo/clients/mojo_renderer_factory.cc
@@ -25,7 +25,7 @@
 MojoRendererFactory::~MojoRendererFactory() = default;
 
 std::unique_ptr<Renderer> MojoRendererFactory::CreateRenderer(
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
     const scoped_refptr<base::TaskRunner>& worker_task_runner,
     AudioRendererSink* audio_renderer_sink,
     VideoRendererSink* video_renderer_sink,
@@ -52,7 +52,7 @@
         renderer_extension_receiver,
     mojo::PendingRemote<mojom::MediaFoundationRendererClientExtension>
         client_extension_remote,
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
     VideoRendererSink* video_renderer_sink) {
   DCHECK(interface_factory_);
   mojo::PendingRemote<mojom::Renderer> renderer_remote;
@@ -70,7 +70,7 @@
 
 #if BUILDFLAG(ENABLE_CAST_RENDERER)
 std::unique_ptr<MojoRenderer> MojoRendererFactory::CreateCastRenderer(
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
     VideoRendererSink* video_renderer_sink) {
   DCHECK(interface_factory_);
 
@@ -92,7 +92,7 @@
     const std::string& presentation_id,
     mojo::PendingRemote<mojom::FlingingRendererClientExtension>
         client_extension_remote,
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
     VideoRendererSink* video_renderer_sink) {
   DCHECK(interface_factory_);
   mojo::PendingRemote<mojom::Renderer> renderer_remote;
@@ -111,7 +111,7 @@
         renderer_extension_receiver,
     mojo::PendingRemote<mojom::MediaPlayerRendererClientExtension>
         client_extension_remote,
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
     VideoRendererSink* video_renderer_sink) {
   DCHECK(interface_factory_);
   mojo::PendingRemote<mojom::Renderer> renderer_remote;
diff --git a/media/mojo/clients/mojo_renderer_factory.h b/media/mojo/clients/mojo_renderer_factory.h
index e36799e..58e7b22a 100644
--- a/media/mojo/clients/mojo_renderer_factory.h
+++ b/media/mojo/clients/mojo_renderer_factory.h
@@ -41,7 +41,7 @@
   ~MojoRendererFactory() final;
 
   std::unique_ptr<Renderer> CreateRenderer(
-      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+      const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
       const scoped_refptr<base::TaskRunner>& worker_task_runner,
       AudioRendererSink* audio_renderer_sink,
       VideoRendererSink* video_renderer_sink,
@@ -55,13 +55,13 @@
           renderer_extension_receiver,
       mojo::PendingRemote<mojom::MediaFoundationRendererClientExtension>
           client_extension_remote,
-      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+      const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
       VideoRendererSink* video_renderer_sink);
 #endif  // BUILDFLAG(IS_WIN)
 
 #if BUILDFLAG(ENABLE_CAST_RENDERER)
   std::unique_ptr<MojoRenderer> CreateCastRenderer(
-      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+      const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
       VideoRendererSink* video_renderer_sink);
 #endif  // BUILDFLAG(ENABLE_CAST_RENDERER)
 
@@ -70,7 +70,7 @@
       const std::string& presentation_id,
       mojo::PendingRemote<mojom::FlingingRendererClientExtension>
           client_extenion_ptr,
-      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+      const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
       VideoRendererSink* video_renderer_sink);
 
   std::unique_ptr<MojoRenderer> CreateMediaPlayerRenderer(
@@ -78,7 +78,7 @@
           renderer_extension_receiver,
       mojo::PendingRemote<mojom::MediaPlayerRendererClientExtension>
           client_extension_remote,
-      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+      const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
       VideoRendererSink* video_renderer_sink);
 #endif  // defined (OS_ANDROID)
 
diff --git a/media/mojo/clients/win/media_foundation_renderer_client.cc b/media/mojo/clients/win/media_foundation_renderer_client.cc
index b3d6f43..6342a70 100644
--- a/media/mojo/clients/win/media_foundation_renderer_client.cc
+++ b/media/mojo/clients/win/media_foundation_renderer_client.cc
@@ -20,7 +20,7 @@
 namespace media {
 
 MediaFoundationRendererClient::MediaFoundationRendererClient(
-    scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+    scoped_refptr<base::SequencedTaskRunner> media_task_runner,
     std::unique_ptr<MediaLog> media_log,
     std::unique_ptr<MojoRenderer> mojo_renderer,
     mojo::PendingRemote<RendererExtension> pending_renderer_extension,
@@ -55,7 +55,7 @@
                                                RendererClient* client,
                                                PipelineStatusCallback init_cb) {
   DVLOG_FUNC(1);
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(!init_cb_);
 
   // Consume and bind the delayed PendingRemote and PendingReceiver now that
@@ -145,7 +145,7 @@
     const base::UnguessableToken& frame_token,
     const gfx::Size& size,
     base::TimeDelta timestamp) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(has_video_);
 
   auto video_frame = video_frame_pool_.find(frame_token);
@@ -187,7 +187,7 @@
 
 void MediaFoundationRendererClient::OnPaintComplete(
     const base::UnguessableToken& token) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   renderer_extension_->NotifyFrameReleased(token);
 }
 
@@ -221,7 +221,7 @@
 }
 
 void MediaFoundationRendererClient::StartPlayingFrom(base::TimeDelta time) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   SignalMediaPlayingStateChange(true);
   next_video_frame_.reset();
   mojo_renderer_->StartPlayingFrom(time);
@@ -306,7 +306,7 @@
 void MediaFoundationRendererClient::OnVideoNaturalSizeChange(
     const gfx::Size& size) {
   DVLOG_FUNC(1) << "size=" << size.ToString();
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(has_video_);
 
   natural_size_ = size;
@@ -378,7 +378,7 @@
 void MediaFoundationRendererClient::OnRemoteRendererInitialized(
     PipelineStatus status) {
   DVLOG_FUNC(1) << "status=" << status;
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(!init_cb_.is_null());
 
   if (status != PIPELINE_OK) {
@@ -413,7 +413,7 @@
 
 void MediaFoundationRendererClient::OnOutputRectChange(gfx::Rect output_rect) {
   DVLOG_FUNC(1) << "output_rect=" << output_rect.ToString();
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(has_video_);
 
   renderer_extension_->SetOutputRect(
@@ -426,7 +426,7 @@
     const gfx::Size& output_size,
     bool success) {
   DVLOG_FUNC(1) << "output_size=" << output_size.ToString();
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(has_video_);
 
   if (!success) {
@@ -483,7 +483,7 @@
     const std::string& error) {
   DVLOG_FUNC(1);
   DCHECK(has_video_);
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   // The error should've already been handled in MediaFoundationRenderer.
   if (!token) {
@@ -499,7 +499,7 @@
 
 void MediaFoundationRendererClient::OnDCOMPSurfaceHandleSet(bool success) {
   DVLOG_FUNC(1);
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(has_video_);
 
   if (!success) {
@@ -514,7 +514,7 @@
     scoped_refptr<VideoFrame> video_frame,
     const gpu::Mailbox& mailbox) {
   DVLOG_FUNC(1);
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(has_video_);
 
   video_frame->metadata().allow_overlay = true;
@@ -542,7 +542,7 @@
 
 void MediaFoundationRendererClient::OnConnectionError() {
   DVLOG_FUNC(1);
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   MEDIA_LOG(ERROR, media_log_) << "MediaFoundationRendererClient disconnected";
   MediaFoundationRenderer::ReportErrorReason(
       MediaFoundationRenderer::ErrorReason::kOnConnectionError);
@@ -570,7 +570,7 @@
 void MediaFoundationRendererClient::OnOverlayStateChanged(
     const gpu::Mailbox& mailbox,
     bool promoted) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   promoted_to_overlay_signal_ = promoted;
   MEDIA_LOG(INFO, media_log_)
       << "Overlay state signal, promoted = " << promoted;
diff --git a/media/mojo/clients/win/media_foundation_renderer_client.h b/media/mojo/clients/win/media_foundation_renderer_client.h
index b2d0aea5..7d47baf 100644
--- a/media/mojo/clients/win/media_foundation_renderer_client.h
+++ b/media/mojo/clients/win/media_foundation_renderer_client.h
@@ -58,7 +58,7 @@
   using ClientExtension = media::mojom::MediaFoundationRendererClientExtension;
 
   MediaFoundationRendererClient(
-      scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+      scoped_refptr<base::SequencedTaskRunner> media_task_runner,
       std::unique_ptr<MediaLog> media_log,
       std::unique_ptr<MojoRenderer> mojo_renderer,
       mojo::PendingRemote<RendererExtension> pending_renderer_extension,
@@ -143,7 +143,7 @@
   // This class is constructed on the main thread. Hence we store
   // PendingRemotes so we can bind the Remotes on the media task
   // runner during/after Initialize().
-  scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+  scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
   std::unique_ptr<MediaLog> media_log_;
   std::unique_ptr<MojoRenderer> mojo_renderer_;
   mojo::PendingRemote<RendererExtension> pending_renderer_extension_;
diff --git a/media/mojo/clients/win/media_foundation_renderer_client_factory.cc b/media/mojo/clients/win/media_foundation_renderer_client_factory.cc
index 6d0862e5..af7e619a 100644
--- a/media/mojo/clients/win/media_foundation_renderer_client_factory.cc
+++ b/media/mojo/clients/win/media_foundation_renderer_client_factory.cc
@@ -41,7 +41,7 @@
 
 std::unique_ptr<media::Renderer>
 MediaFoundationRendererClientFactory::CreateRenderer(
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
     const scoped_refptr<base::TaskRunner>& /*worker_task_runner*/,
     media::AudioRendererSink* /*audio_renderer_sink*/,
     media::VideoRendererSink* video_renderer_sink,
diff --git a/media/mojo/clients/win/media_foundation_renderer_client_factory.h b/media/mojo/clients/win/media_foundation_renderer_client_factory.h
index d57f64a..d1ba1e6 100644
--- a/media/mojo/clients/win/media_foundation_renderer_client_factory.h
+++ b/media/mojo/clients/win/media_foundation_renderer_client_factory.h
@@ -7,6 +7,7 @@
 
 #include "base/callback.h"
 #include "base/memory/raw_ptr.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/task/single_thread_task_runner.h"
 #include "media/base/renderer_factory.h"
 #include "media/base/win/dcomp_texture_wrapper.h"
@@ -36,7 +37,7 @@
   ~MediaFoundationRendererClientFactory() override;
 
   std::unique_ptr<media::Renderer> CreateRenderer(
-      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+      const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
       const scoped_refptr<base::TaskRunner>& worker_task_runner,
       media::AudioRendererSink* audio_renderer_sink,
       media::VideoRendererSink* video_renderer_sink,
diff --git a/media/remoting/courier_renderer.cc b/media/remoting/courier_renderer.cc
index 16f662ef..8cc6d60 100644
--- a/media/remoting/courier_renderer.cc
+++ b/media/remoting/courier_renderer.cc
@@ -79,7 +79,7 @@
 }  // namespace
 
 CourierRenderer::CourierRenderer(
-    scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+    scoped_refptr<base::SequencedTaskRunner> media_task_runner,
     const base::WeakPtr<RendererController>& controller,
     VideoRendererSink* video_renderer_sink)
     : state_(STATE_UNINITIALIZED),
@@ -102,7 +102,7 @@
 }
 
 CourierRenderer::~CourierRenderer() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   DeregisterFromRpcMessaging();
   if (video_renderer_sink_) {
@@ -114,7 +114,7 @@
 void CourierRenderer::Initialize(MediaResource* media_resource,
                                  RendererClient* client,
                                  PipelineStatusCallback init_cb) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(media_resource);
   DCHECK(client);
 
@@ -155,7 +155,7 @@
     absl::optional<base::TimeDelta> latency_hint) {}
 
 void CourierRenderer::Flush(base::OnceClosure flush_cb) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(!flush_cb_);
 
   if (state_ != STATE_PLAYING) {
@@ -200,7 +200,7 @@
 }
 
 void CourierRenderer::StartPlayingFrom(base::TimeDelta time) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   if (state_ != STATE_PLAYING) {
     DCHECK_EQ(state_, STATE_ERROR);
@@ -222,7 +222,7 @@
 }
 
 void CourierRenderer::SetPlaybackRate(double playback_rate) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   if (state_ != STATE_FLUSHING && state_ != STATE_PLAYING) {
     DCHECK_EQ(state_, STATE_ERROR);
@@ -240,7 +240,7 @@
 }
 
 void CourierRenderer::SetVolume(float volume) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   volume_ = volume;
   if (state_ != STATE_FLUSHING && state_ != STATE_PLAYING)
@@ -267,7 +267,7 @@
 
 // static
 void CourierRenderer::OnDataPipeCreatedOnMainThread(
-    scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+    scoped_refptr<base::SequencedTaskRunner> media_task_runner,
     base::WeakPtr<CourierRenderer> self,
     openscreen::WeakPtr<RpcMessenger> rpc_messenger,
     mojo::PendingRemote<mojom::RemotingDataStreamSender> audio,
@@ -292,7 +292,7 @@
     mojo::ScopedDataPipeProducerHandle video_handle,
     int audio_rpc_handle,
     int video_rpc_handle) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   if (state_ == STATE_ERROR)
     return;  // Abort because something went wrong in the meantime.
@@ -360,7 +360,7 @@
 
 // static
 void CourierRenderer::OnMessageReceivedOnMainThread(
-    scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+    scoped_refptr<base::SequencedTaskRunner> media_task_runner,
     base::WeakPtr<CourierRenderer> self,
     std::unique_ptr<openscreen::cast::RpcMessage> message) {
   if (media_task_runner) {
@@ -374,7 +374,7 @@
 
 void CourierRenderer::OnReceivedRpc(
     std::unique_ptr<openscreen::cast::RpcMessage> message) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(message);
   switch (message->proc()) {
     case openscreen::cast::RpcMessage::RPC_ACQUIRE_RENDERER_DONE:
@@ -421,7 +421,7 @@
 
 void CourierRenderer::SendRpcToRemote(
     std::unique_ptr<openscreen::cast::RpcMessage> message) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(main_task_runner_);
   main_task_runner_->PostTask(FROM_HERE,
                               base::BindOnce(&RpcMessenger::SendMessageToRemote,
@@ -430,7 +430,7 @@
 
 void CourierRenderer::AcquireRendererDone(
     std::unique_ptr<openscreen::cast::RpcMessage> message) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(message);
 
   remote_renderer_handle_ = message->integer_value();
@@ -462,7 +462,7 @@
 
 void CourierRenderer::InitializeCallback(
     std::unique_ptr<openscreen::cast::RpcMessage> message) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(message);
 
   const bool success = message->boolean_value();
@@ -485,7 +485,7 @@
 }
 
 void CourierRenderer::FlushUntilCallback() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   if (state_ != STATE_FLUSHING || !flush_cb_) {
     OnFatalError(PEERS_OUT_OF_SYNC);
@@ -503,7 +503,7 @@
 
 void CourierRenderer::OnTimeUpdate(
     std::unique_ptr<openscreen::cast::RpcMessage> message) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(message);
   // Shutdown remoting session if receiving malformed RPC message.
   if (!message->has_rendererclient_ontimeupdate_rpc()) {
@@ -532,7 +532,7 @@
 
 void CourierRenderer::OnBufferingStateChange(
     std::unique_ptr<openscreen::cast::RpcMessage> message) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(message);
   if (!message->has_rendererclient_onbufferingstatechange_rpc()) {
     OnFatalError(RPC_INVALID);
@@ -559,7 +559,7 @@
 
 void CourierRenderer::OnAudioConfigChange(
     std::unique_ptr<openscreen::cast::RpcMessage> message) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(message);
   // Shutdown remoting session if receiving malformed RPC message.
   if (!message->has_rendererclient_onaudioconfigchange_rpc()) {
@@ -581,7 +581,7 @@
 
 void CourierRenderer::OnVideoConfigChange(
     std::unique_ptr<openscreen::cast::RpcMessage> message) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(message);
   // Shutdown remoting session if receiving malformed RPC message.
   if (!message->has_rendererclient_onvideoconfigchange_rpc()) {
@@ -603,7 +603,7 @@
 
 void CourierRenderer::OnVideoNaturalSizeChange(
     std::unique_ptr<openscreen::cast::RpcMessage> message) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(message);
   // Shutdown remoting session if receiving malformed RPC message.
   if (!message->has_rendererclient_onvideonatualsizechange_rpc()) {
@@ -620,7 +620,7 @@
 
 void CourierRenderer::OnVideoOpacityChange(
     std::unique_ptr<openscreen::cast::RpcMessage> message) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(message);
   const bool opaque = message->boolean_value();
   client_->OnVideoOpacityChange(opaque);
@@ -628,7 +628,7 @@
 
 void CourierRenderer::OnStatisticsUpdate(
     std::unique_ptr<openscreen::cast::RpcMessage> message) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(message);
   // Shutdown remoting session if receiving malformed RPC message.
   if (!message->has_rendererclient_onstatisticsupdate_rpc()) {
@@ -648,7 +648,7 @@
 }
 
 void CourierRenderer::OnFatalError(StopTrigger stop_trigger) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK_NE(UNKNOWN_STOP_TRIGGER, stop_trigger);
 
   // If this is the first error, notify the controller. It is expected the
@@ -674,7 +674,7 @@
 }
 
 void CourierRenderer::OnMediaTimeUpdated() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   if (flush_cb_)
     return;  // Don't manage and check the queue when Flush() is on-going.
   if (receiver_is_blocked_on_local_demuxers_)
@@ -713,7 +713,7 @@
 
 void CourierRenderer::UpdateVideoStatsQueue(int video_frames_decoded,
                                             int video_frames_dropped) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   if (flush_cb_)
     return;  // Don't manage and check the queue when Flush() is on-going.
 
@@ -754,7 +754,7 @@
 }
 
 void CourierRenderer::ResetMeasurements() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   media_time_queue_.clear();
   video_stats_queue_.clear();
   sum_video_frames_dropped_ = 0;
@@ -770,7 +770,7 @@
 }
 
 void CourierRenderer::MeasureAndRecordDataRates() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   // Whenever media is first started or flushed/seeked, there is a "burst
   // bufferring" period as the remote device rapidly fills its buffer before
@@ -810,7 +810,7 @@
 }
 
 bool CourierRenderer::IsWaitingForDataFromDemuxers() const {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   return ((video_demuxer_stream_adapter_ &&
            video_demuxer_stream_adapter_->is_processing_read_request() &&
            !video_demuxer_stream_adapter_->is_data_pending()) ||
@@ -820,7 +820,7 @@
 }
 
 void CourierRenderer::RegisterForRpcMessaging() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   auto receive_callback = BindToCurrentLoop(base::BindRepeating(
       &CourierRenderer::OnReceivedRpc, weak_factory_.GetWeakPtr()));
 
@@ -836,7 +836,7 @@
 }
 
 void CourierRenderer::DeregisterFromRpcMessaging() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   if (rpc_messenger_) {
     main_task_runner_->PostTask(
         FROM_HERE,
diff --git a/media/remoting/courier_renderer.h b/media/remoting/courier_renderer.h
index 82ead88..b2cd3b9 100644
--- a/media/remoting/courier_renderer.h
+++ b/media/remoting/courier_renderer.h
@@ -47,7 +47,7 @@
   // The whole class except for constructor and GetMediaTime() runs on
   // |media_task_runner|. The constructor and GetMediaTime() run on render main
   // thread.
-  CourierRenderer(scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+  CourierRenderer(scoped_refptr<base::SequencedTaskRunner> media_task_runner,
                   const base::WeakPtr<RendererController>& controller,
                   VideoRendererSink* video_renderer_sink);
 
@@ -61,7 +61,7 @@
   // static in order to post task to media thread in order to avoid threading
   // race condition.
   static void OnDataPipeCreatedOnMainThread(
-      scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+      scoped_refptr<base::SequencedTaskRunner> media_task_runner,
       base::WeakPtr<CourierRenderer> self,
       openscreen::WeakPtr<openscreen::cast::RpcMessenger> rpc_messenger,
       mojo::PendingRemote<mojom::RemotingDataStreamSender> audio,
@@ -73,7 +73,7 @@
   // static in order to post task to media thread in order to avoid threading
   // race condition.
   static void OnMessageReceivedOnMainThread(
-      scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+      scoped_refptr<base::SequencedTaskRunner> media_task_runner,
       base::WeakPtr<CourierRenderer> self,
       std::unique_ptr<openscreen::cast::RpcMessage> message);
 
@@ -170,7 +170,7 @@
 
   State state_;
   const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
-  const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+  const scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
 
   // Current renderer playback time information.
   base::TimeDelta current_media_time_;
diff --git a/media/remoting/courier_renderer_factory.cc b/media/remoting/courier_renderer_factory.cc
index 86d5941..7d497701 100644
--- a/media/remoting/courier_renderer_factory.cc
+++ b/media/remoting/courier_renderer_factory.cc
@@ -26,7 +26,7 @@
 CourierRendererFactory::~CourierRendererFactory() = default;
 
 std::unique_ptr<Renderer> CourierRendererFactory::CreateRenderer(
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
     const scoped_refptr<base::TaskRunner>& worker_task_runner,
     AudioRendererSink* audio_renderer_sink,
     VideoRendererSink* video_renderer_sink,
diff --git a/media/remoting/courier_renderer_factory.h b/media/remoting/courier_renderer_factory.h
index 0b88436..8d6c391 100644
--- a/media/remoting/courier_renderer_factory.h
+++ b/media/remoting/courier_renderer_factory.h
@@ -23,7 +23,7 @@
   ~CourierRendererFactory() override;
 
   std::unique_ptr<Renderer> CreateRenderer(
-      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+      const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
       const scoped_refptr<base::TaskRunner>& worker_task_runner,
       AudioRendererSink* audio_renderer_sink,
       VideoRendererSink* video_renderer_sink,
diff --git a/media/remoting/demuxer_stream_adapter.cc b/media/remoting/demuxer_stream_adapter.cc
index 385b40c..8059fbd 100644
--- a/media/remoting/demuxer_stream_adapter.cc
+++ b/media/remoting/demuxer_stream_adapter.cc
@@ -9,6 +9,7 @@
 #include "base/base64.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/task/single_thread_task_runner.h"
 #include "components/cast_streaming/public/remoting_proto_enum_utils.h"
 #include "components/cast_streaming/public/remoting_proto_utils.h"
@@ -47,7 +48,7 @@
 
 DemuxerStreamAdapter::DemuxerStreamAdapter(
     scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
-    scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+    scoped_refptr<base::SequencedTaskRunner> media_task_runner,
     const std::string& name,
     DemuxerStream* demuxer_stream,
     const openscreen::WeakPtr<RpcMessenger>& rpc_messenger,
@@ -74,7 +75,7 @@
       bytes_written_to_pipe_(0) {
   DCHECK(main_task_runner_);
   DCHECK(media_task_runner_);
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(demuxer_stream);
   DCHECK(!error_callback_.is_null());
 
@@ -87,19 +88,19 @@
 }
 
 DemuxerStreamAdapter::~DemuxerStreamAdapter() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DeregisterFromRpcMessaging();
 }
 
 int64_t DemuxerStreamAdapter::GetBytesWrittenAndReset() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   const int64_t current_count = bytes_written_to_pipe_;
   bytes_written_to_pipe_ = 0;
   return current_count;
 }
 
 absl::optional<uint32_t> DemuxerStreamAdapter::SignalFlush(bool flushing) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DEMUXER_VLOG(2) << "flushing=" << flushing;
 
   // Ignores if |pending_flush_| states is same.
@@ -124,7 +125,7 @@
 
 void DemuxerStreamAdapter::OnReceivedRpc(
     std::unique_ptr<openscreen::cast::RpcMessage> message) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(message);
   DCHECK(rpc_handle_ == message->handle());
 
@@ -147,7 +148,7 @@
 }
 
 void DemuxerStreamAdapter::Initialize(int remote_callback_handle) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(!pending_flush_);
   DEMUXER_VLOG(2) << "Received RPC_DS_INITIALIZE with remote_callback_handle="
                   << remote_callback_handle;
@@ -208,7 +209,7 @@
 
 void DemuxerStreamAdapter::ReadUntil(
     std::unique_ptr<openscreen::cast::RpcMessage> message) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(message);
   if (!message->has_demuxerstream_readuntil_rpc()) {
     DEMUXER_VLOG(1) << "Missing required DemuxerStreamReadUntil struct in RPC";
@@ -244,7 +245,7 @@
 }
 
 void DemuxerStreamAdapter::EnableBitstreamConverter() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DEMUXER_VLOG(2) << "Received RPC_DS_ENABLEBITSTREAMCONVERTER";
   bool is_command_sent = true;
 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
@@ -268,7 +269,7 @@
 }
 
 void DemuxerStreamAdapter::RequestBuffer() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   if (!is_processing_read_request() || pending_flush_) {
     DEMUXER_VLOG(2) << "Skip actions since it's not in the reading state";
     return;
@@ -281,7 +282,7 @@
 void DemuxerStreamAdapter::OnNewBuffer(DemuxerStream::Status status,
                                        scoped_refptr<DecoderBuffer> input) {
   DEMUXER_VLOG(3) << "status=" << status;
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   if (!is_processing_read_request() || pending_flush_) {
     DEMUXER_VLOG(2) << "Skip actions since it's not in the reading state";
     return;
@@ -324,7 +325,7 @@
 }
 
 void DemuxerStreamAdapter::WriteFrame() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(!pending_flush_);
   DCHECK(is_processing_read_request());
   DCHECK(!pending_frame_.empty());
@@ -366,7 +367,7 @@
 }
 
 void DemuxerStreamAdapter::SendReadAck() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DEMUXER_VLOG(3) << "last_count_=" << last_count_
                   << ", remote_read_callback_handle="
                   << read_until_callback_handle_
@@ -420,13 +421,13 @@
 }
 
 void DemuxerStreamAdapter::ResetPendingFrame() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   pending_frame_.clear();
   pending_frame_is_eos_ = false;
 }
 
 void DemuxerStreamAdapter::OnFatalError(StopTrigger stop_trigger) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   DEMUXER_VLOG(1) << __func__ << " with StopTrigger " << stop_trigger;
 
@@ -439,7 +440,7 @@
 }
 
 void DemuxerStreamAdapter::RegisterForRpcMessaging() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   auto receive_callback = BindToCurrentLoop(base::BindRepeating(
       &DemuxerStreamAdapter::OnReceivedRpc, weak_factory_.GetWeakPtr()));
   main_task_runner_->PostTask(
@@ -453,7 +454,7 @@
 }
 
 void DemuxerStreamAdapter::DeregisterFromRpcMessaging() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   if (rpc_messenger_) {
     main_task_runner_->PostTask(
         FROM_HERE,
diff --git a/media/remoting/demuxer_stream_adapter.h b/media/remoting/demuxer_stream_adapter.h
index 5f24a48..8f14e51 100644
--- a/media/remoting/demuxer_stream_adapter.h
+++ b/media/remoting/demuxer_stream_adapter.h
@@ -13,6 +13,7 @@
 #include "base/callback_forward.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
+#include "base/task/sequenced_task_runner.h"
 #include "media/base/audio_decoder_config.h"
 #include "media/base/demuxer_stream.h"
 #include "media/base/video_decoder_config.h"
@@ -63,7 +64,7 @@
   //                   be shut down.
   DemuxerStreamAdapter(
       scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
-      scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+      scoped_refptr<base::SequencedTaskRunner> media_task_runner,
       const std::string& name,
       DemuxerStream* demuxer_stream,
       const openscreen::WeakPtr<openscreen::cast::RpcMessenger>& rpc_messenger,
@@ -139,7 +140,7 @@
   void DeregisterFromRpcMessaging();
 
   const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
-  const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+  const scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
 
   // Name of demuxer stream. Debug only.
   const std::string name_;
diff --git a/media/remoting/receiver.cc b/media/remoting/receiver.cc
index 1fd9e8a..4d6ef125 100644
--- a/media/remoting/receiver.cc
+++ b/media/remoting/receiver.cc
@@ -36,7 +36,7 @@
     int rpc_handle,
     int remote_handle,
     ReceiverController* receiver_controller,
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
     std::unique_ptr<Renderer> renderer,
     base::OnceCallback<void(int)> acquire_renderer_done_cb)
     : rpc_handle_(rpc_handle),
@@ -120,7 +120,7 @@
 
 void Receiver::OnReceivedRpc(
     std::unique_ptr<openscreen::cast::RpcMessage> message) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(message);
 
   cast_streaming::remoting::DispatchRendererRpcCall(message.get(), this);
@@ -156,7 +156,7 @@
   if (!rpc_initialize_received_ || !init_cb_)
     return;
 
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(renderer_);
   DCHECK(demuxer_);
   renderer_->Initialize(demuxer_, this,
@@ -165,7 +165,7 @@
 }
 
 void Receiver::OnRendererInitialized(PipelineStatus status) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(init_cb_);
   std::move(init_cb_).Run(status);
 
@@ -176,7 +176,7 @@
 }
 
 void Receiver::OnRpcSetPlaybackRate(double playback_rate) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
 
   renderer_->SetPlaybackRate(playback_rate);
 
@@ -193,7 +193,7 @@
 }
 
 void Receiver::OnRpcFlush(uint32_t audio_count, uint32_t video_count) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
 
   receiver_controller_->OnRendererFlush(audio_count, video_count);
 
@@ -209,7 +209,7 @@
 }
 
 void Receiver::OnRpcStartPlayingFrom(base::TimeDelta time) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
 
   renderer_->StartPlayingFrom(time);
   ScheduleMediaTimeUpdates();
@@ -225,7 +225,7 @@
 }
 
 void Receiver::OnRpcSetVolume(double volume) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
   renderer_->SetVolume(volume);
 }
 
diff --git a/media/remoting/receiver.h b/media/remoting/receiver.h
index bbc9751a..c2a1da5 100644
--- a/media/remoting/receiver.h
+++ b/media/remoting/receiver.h
@@ -54,7 +54,7 @@
   Receiver(int rpc_handle,
            int remote_handle,
            ReceiverController* receiver_controller,
-           const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+           const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
            std::unique_ptr<Renderer> renderer,
            base::OnceCallback<void(int)> acquire_renderer_done_cb);
   ~Receiver() override;
@@ -140,7 +140,7 @@
   const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
 
   // Media tasks should run on media thread.
-  const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+  const scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
 
   // |renderer_| is the real renderer to render media.
   std::unique_ptr<Renderer> renderer_;
diff --git a/media/remoting/remoting_renderer_factory.cc b/media/remoting/remoting_renderer_factory.cc
index 90eaf3a..c3d5489 100644
--- a/media/remoting/remoting_renderer_factory.cc
+++ b/media/remoting/remoting_renderer_factory.cc
@@ -19,7 +19,7 @@
 RemotingRendererFactory::RemotingRendererFactory(
     mojo::PendingRemote<mojom::Remotee> remotee,
     std::unique_ptr<RendererFactory> renderer_factory,
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner)
+    const scoped_refptr<base::SequencedTaskRunner>& media_task_runner)
     : receiver_controller_(ReceiverController::GetInstance()),
       rpc_messenger_(receiver_controller_->rpc_messenger()),
       renderer_handle_(rpc_messenger_->GetUniqueHandle()),
@@ -49,7 +49,7 @@
 }
 
 std::unique_ptr<Renderer> RemotingRendererFactory::CreateRenderer(
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
     const scoped_refptr<base::TaskRunner>& worker_task_runner,
     AudioRendererSink* audio_renderer_sink,
     VideoRendererSink* video_renderer_sink,
diff --git a/media/remoting/remoting_renderer_factory.h b/media/remoting/remoting_renderer_factory.h
index 9ddd45bd..142e470b0 100644
--- a/media/remoting/remoting_renderer_factory.h
+++ b/media/remoting/remoting_renderer_factory.h
@@ -6,6 +6,7 @@
 #define MEDIA_REMOTING_REMOTING_RENDERER_FACTORY_H_
 
 #include "base/memory/raw_ptr.h"
+#include "base/task/sequenced_task_runner.h"
 #include "media/base/renderer_factory.h"
 #include "media/mojo/mojom/remoting.mojom.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
@@ -22,12 +23,12 @@
   RemotingRendererFactory(
       mojo::PendingRemote<mojom::Remotee> remotee,
       std::unique_ptr<RendererFactory> renderer_factory,
-      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner);
+      const scoped_refptr<base::SequencedTaskRunner>& media_task_runner);
   ~RemotingRendererFactory() override;
 
   // RendererFactory implementation
   std::unique_ptr<Renderer> CreateRenderer(
-      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+      const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
       const scoped_refptr<base::TaskRunner>& worker_task_runner,
       AudioRendererSink* audio_renderer_sink,
       VideoRendererSink* video_renderer_sink,
@@ -62,8 +63,7 @@
   std::unique_ptr<RendererFactory> real_renderer_factory_;
 
   // Used to instantiate |receiver_|.
-  const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
-
+  const scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
   base::WeakPtrFactory<RemotingRendererFactory> weak_factory_{this};
 };
 
diff --git a/media/remoting/stream_provider.cc b/media/remoting/stream_provider.cc
index f5b15218..7adb672 100644
--- a/media/remoting/stream_provider.cc
+++ b/media/remoting/stream_provider.cc
@@ -37,7 +37,7 @@
     RpcMessenger* rpc_messenger,
     Type type,
     int32_t handle,
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
     base::OnceCallback<void(MediaStream::UniquePtr)> callback) {
   MediaStream::UniquePtr stream(
       new MediaStream(rpc_messenger, type, handle, media_task_runner),
@@ -54,7 +54,7 @@
     RpcMessenger* rpc_messenger,
     Type type,
     int remote_handle,
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner)
+    const scoped_refptr<base::SequencedTaskRunner>& media_task_runner)
     : main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
       media_task_runner_(media_task_runner),
       rpc_messenger_(rpc_messenger),
@@ -81,7 +81,7 @@
 }
 
 void StreamProvider::MediaStream::Destroy() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   // Invalid weak pointers to prevent |this| from receiving RPC calls on the
   // media thread.
@@ -107,7 +107,7 @@
 
 void StreamProvider::MediaStream::Initialize(
     base::OnceClosure init_done_callback) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(init_done_callback);
 
   if (init_done_callback_) {
@@ -126,7 +126,7 @@
 
 void StreamProvider::MediaStream::InitializeDataPipe(
     mojo::ScopedDataPipeConsumerHandle data_pipe) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   decoder_buffer_reader_ =
       std::make_unique<MojoDecoderBufferReader>(std::move(data_pipe));
@@ -135,7 +135,7 @@
 
 void StreamProvider::MediaStream::ReceiveFrame(uint32_t count,
                                                mojom::DecoderBufferPtr buffer) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(decoder_buffer_reader_);
 
   auto callback = BindToCurrentLoop(
@@ -145,7 +145,7 @@
 }
 
 void StreamProvider::MediaStream::FlushUntil(uint32_t count) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   if (count < current_frame_count_)
     return;
@@ -168,7 +168,7 @@
 
 void StreamProvider::MediaStream::OnReceivedRpc(
     std::unique_ptr<openscreen::cast::RpcMessage> message) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(message->handle() == rpc_handle_);
 
   switch (message->proc()) {
@@ -185,7 +185,7 @@
 
 void StreamProvider::MediaStream::OnInitializeCallback(
     std::unique_ptr<openscreen::cast::RpcMessage> message) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   const openscreen::cast::DemuxerStreamInitializeCallback callback_message =
       message->demuxerstream_initializecb_rpc();
   if (callback_message.type() != type_) {
@@ -231,7 +231,7 @@
 }
 
 void StreamProvider::MediaStream::CompleteInitialize() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   // Initialization finished when received RPC_DS_INITIALIZE_CALLBACK and
   // |decoder_buffer_reader_| is created.
@@ -248,7 +248,7 @@
 
 void StreamProvider::MediaStream::OnReadUntilCallback(
     std::unique_ptr<openscreen::cast::RpcMessage> message) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   if (!read_until_sent_) {
     OnError("Unexpected ReadUntilCallback");
@@ -325,7 +325,7 @@
 }
 
 void StreamProvider::MediaStream::Read(ReadCB read_cb) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(read_complete_callback_.is_null());
   DCHECK(read_cb);
 
@@ -346,7 +346,7 @@
 }
 
 void StreamProvider::MediaStream::CompleteRead(DemuxerStream::Status status) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   switch (status) {
     case DemuxerStream::kConfigChanged:
@@ -401,7 +401,7 @@
 void StreamProvider::MediaStream::AppendBuffer(
     uint32_t count,
     scoped_refptr<DecoderBuffer> buffer) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   // Drop flushed frame.
   if (count < current_frame_count_)
@@ -426,7 +426,7 @@
 
 StreamProvider::StreamProvider(
     ReceiverController* receiver_controller,
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner)
+    const scoped_refptr<base::SequencedTaskRunner>& media_task_runner)
     : main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
       media_task_runner_(media_task_runner),
       receiver_controller_(receiver_controller),
@@ -459,7 +459,7 @@
 
 void StreamProvider::Initialize(DemuxerHost* host,
                                 PipelineStatusCallback status_cb) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   init_done_callback_ = std::move(status_cb);
   CompleteInitialize();
 }
@@ -514,7 +514,7 @@
 }
 
 void StreamProvider::Destroy() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   if (init_done_callback_)
     std::move(init_done_callback_).Run(PIPELINE_ERROR_ABORT);
@@ -544,7 +544,7 @@
 
 void StreamProvider::OnAcquireDemuxer(
     std::unique_ptr<openscreen::cast::RpcMessage> message) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(message->has_acquire_demuxer_rpc());
 
   int32_t audio_demuxer_handle =
@@ -578,7 +578,7 @@
 }
 
 void StreamProvider::OnAudioStreamCreated(MediaStream::UniquePtr stream) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   audio_stream_ = std::move(stream);
   audio_stream_->Initialize(base::BindOnce(
       &StreamProvider::OnAudioStreamInitialized, media_weak_this_));
@@ -586,7 +586,7 @@
 }
 
 void StreamProvider::OnVideoStreamCreated(MediaStream::UniquePtr stream) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   video_stream_ = std::move(stream);
   video_stream_->Initialize(base::BindOnce(
       &StreamProvider::OnVideoStreamInitialized, media_weak_this_));
@@ -594,7 +594,7 @@
 }
 
 void StreamProvider::InitializeDataPipe() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   if ((has_audio_ && !audio_stream_) || (has_video_ && !video_stream_))
     return;
@@ -617,7 +617,7 @@
 }
 
 void StreamProvider::CompleteInitialize() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   // Haven't receive RpcAcquireRenderer message
   if (!has_audio_ && !has_video_)
diff --git a/media/remoting/stream_provider.h b/media/remoting/stream_provider.h
index 910e6ae..88c49664 100644
--- a/media/remoting/stream_provider.h
+++ b/media/remoting/stream_provider.h
@@ -10,6 +10,7 @@
 #include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/task/sequenced_task_runner_helpers.h"
 #include "base/task/single_thread_task_runner.h"
 #include "media/base/audio_decoder_config.h"
@@ -44,7 +45,7 @@
  public:
   StreamProvider(
       ReceiverController* receiver_controller,
-      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner);
+      const scoped_refptr<base::SequencedTaskRunner>& media_task_runner);
 
   // Demuxer implementation.
   std::vector<DemuxerStream*> GetAllStreams() override;
@@ -87,7 +88,7 @@
         openscreen::cast::RpcMessenger* rpc_messenger,
         Type type,
         int32_t handle,
-        const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+        const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
         base::OnceCallback<void(MediaStream::UniquePtr)> callback);
 
     // In order to destroy members in the right thread, MediaStream has to use
@@ -98,7 +99,7 @@
         openscreen::cast::RpcMessenger* rpc_messenger,
         Type type,
         int32_t remote_handle,
-        const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner);
+        const scoped_refptr<base::SequencedTaskRunner>& media_task_runner);
 
     // DemuxerStream implementation.
     void Read(ReadCB read_cb) override;
@@ -170,7 +171,7 @@
     void OnError(const std::string& error);
 
     scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
-    scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+    scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
 
     const raw_ptr<openscreen::cast::RpcMessenger> rpc_messenger_;
     const Type type_;
@@ -247,7 +248,7 @@
   void CompleteInitialize();
 
   scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
-  scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+  scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
   const raw_ptr<ReceiverController> receiver_controller_;
   const raw_ptr<openscreen::cast::RpcMessenger> rpc_messenger_;
   MediaStream::UniquePtr audio_stream_;
diff --git a/media/renderers/audio_renderer_impl.cc b/media/renderers/audio_renderer_impl.cc
index 65bab13c..9d8dcdb4 100644
--- a/media/renderers/audio_renderer_impl.cc
+++ b/media/renderers/audio_renderer_impl.cc
@@ -18,7 +18,6 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/power_monitor/power_monitor.h"
 #include "base/ranges/algorithm.h"
-#include "base/task/single_thread_task_runner.h"
 #include "base/time/default_tick_clock.h"
 #include "base/time/time.h"
 #include "base/trace_event/trace_event.h"
@@ -43,7 +42,7 @@
 namespace media {
 
 AudioRendererImpl::AudioRendererImpl(
-    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& task_runner,
     AudioRendererSink* sink,
     const CreateAudioDecodersCB& create_audio_decoders_cb,
     MediaLog* media_log,
@@ -79,11 +78,10 @@
       speech_recognition_client_(speech_recognition_client) {
 #endif
   DCHECK(create_audio_decoders_cb_);
-
   // PowerObserver's must be added and removed from the same thread, but we
   // won't remove the observer until we're destructed on |task_runner_| so we
   // must post it here if we're on the wrong thread.
-  if (task_runner_->BelongsToCurrentThread()) {
+  if (task_runner_->RunsTasksInCurrentSequence()) {
     base::PowerMonitor::AddPowerSuspendObserver(this);
   } else {
     // Safe to post this without a WeakPtr because this class must be destructed
@@ -100,7 +98,7 @@
 
 AudioRendererImpl::~AudioRendererImpl() {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   base::PowerMonitor::RemovePowerSuspendObserver(this);
 
   // If Render() is in progress, this call will wait for Render() to finish.
@@ -115,7 +113,7 @@
 
 void AudioRendererImpl::StartTicking() {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   base::AutoLock auto_lock(lock_);
 
@@ -133,7 +131,7 @@
 
 void AudioRendererImpl::StartRendering_Locked() {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK_EQ(state_, kPlaying);
   DCHECK(!sink_playing_);
   DCHECK_NE(playback_rate_, 0.0);
@@ -150,7 +148,7 @@
 
 void AudioRendererImpl::StopTicking() {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   base::AutoLock auto_lock(lock_);
 
@@ -167,7 +165,7 @@
 }
 
 void AudioRendererImpl::StopRendering_Locked() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK_EQ(state_, kPlaying);
   DCHECK(sink_playing_);
   lock_.AssertAcquired();
@@ -185,7 +183,7 @@
 
 void AudioRendererImpl::SetMediaTime(base::TimeDelta time) {
   DVLOG(1) << __func__ << "(" << time << ")";
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   base::AutoLock auto_lock(lock_);
   DCHECK(!rendering_);
@@ -280,7 +278,7 @@
 
 void AudioRendererImpl::Flush(base::OnceClosure callback) {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("media", "AudioRendererImpl::Flush",
                                     TRACE_ID_LOCAL(this));
 
@@ -307,7 +305,7 @@
 }
 
 void AudioRendererImpl::DoFlush_Locked() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   lock_.AssertAcquired();
 
   DCHECK(!pending_read_);
@@ -319,7 +317,7 @@
 }
 
 void AudioRendererImpl::ResetDecoderDone() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   {
     base::AutoLock auto_lock(lock_);
 
@@ -342,7 +340,7 @@
 
 void AudioRendererImpl::StartPlaying() {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   base::AutoLock auto_lock(lock_);
   DCHECK(!sink_playing_);
@@ -359,7 +357,7 @@
                                    RendererClient* client,
                                    PipelineStatusCallback init_cb) {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(client);
   DCHECK(stream);
   DCHECK_EQ(stream->type(), DemuxerStream::AUDIO);
@@ -405,7 +403,7 @@
     CdmContext* cdm_context,
     OutputDeviceInfo output_device_info) {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(client_);
   DCHECK(stream);
   DCHECK_EQ(stream->type(), DemuxerStream::AUDIO);
@@ -640,7 +638,7 @@
 
 void AudioRendererImpl::OnAudioDecoderStreamInitialized(bool success) {
   DVLOG(1) << __func__ << ": " << success;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   base::AutoLock auto_lock(lock_);
 
   if (!success) {
@@ -729,22 +727,22 @@
 }
 
 void AudioRendererImpl::OnPlaybackError(PipelineStatus error) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   client_->OnError(error);
 }
 
 void AudioRendererImpl::OnPlaybackEnded() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   client_->OnEnded();
 }
 
 void AudioRendererImpl::OnStatisticsUpdate(const PipelineStatistics& stats) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   client_->OnStatisticsUpdate(stats);
 }
 
 void AudioRendererImpl::OnBufferingStateChange(BufferingState buffering_state) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   // "Underflow" is only possible when playing. This avoids noise like blaming
   // the decoder for an "underflow" that is really just a seek.
@@ -763,12 +761,12 @@
 }
 
 void AudioRendererImpl::OnWaiting(WaitingReason reason) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   client_->OnWaiting(reason);
 }
 
 void AudioRendererImpl::SetVolume(float volume) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   // Only consider audio as unmuted if the volume is set to a non-zero value
   // when the state is kPlaying.
@@ -868,7 +866,7 @@
 void AudioRendererImpl::DecodedAudioReady(
     AudioDecoderStream::ReadResult result) {
   DVLOG(2) << __func__ << "(" << static_cast<int>(result.code()) << ")";
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   base::AutoLock auto_lock(lock_);
   DCHECK(state_ != kUninitialized);
@@ -1091,7 +1089,7 @@
 }
 
 void AudioRendererImpl::AttemptRead_Locked() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   lock_.AssertAcquired();
 
   if (!CanRead_Locked())
@@ -1127,7 +1125,7 @@
 
 void AudioRendererImpl::SetPlaybackRate(double playback_rate) {
   DVLOG(1) << __func__ << "(" << playback_rate << ")";
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK_GE(playback_rate, 0);
   DCHECK(sink_);
 
@@ -1355,7 +1353,7 @@
 }
 
 void AudioRendererImpl::HandleAbortedReadOrDecodeError(PipelineStatus status) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   lock_.AssertAcquired();
 
   switch (state_) {
@@ -1394,7 +1392,7 @@
 }
 
 void AudioRendererImpl::OnConfigChange(const AudioDecoderConfig& config) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(expecting_config_changes_);
   buffer_converter_->ResetTimestampState();
 
@@ -1453,7 +1451,7 @@
 
 void AudioRendererImpl::EnableSpeechRecognition() {
 #if !BUILDFLAG(IS_ANDROID)
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   transcribe_audio_callback_ = base::BindRepeating(
       &AudioRendererImpl::TranscribeAudio, weak_factory_.GetWeakPtr());
 #endif
@@ -1462,7 +1460,7 @@
 void AudioRendererImpl::TranscribeAudio(
     scoped_refptr<media::AudioBuffer> buffer) {
 #if !BUILDFLAG(IS_ANDROID)
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   if (speech_recognition_client_)
     speech_recognition_client_->AddAudio(std::move(buffer));
 #endif
diff --git a/media/renderers/audio_renderer_impl.h b/media/renderers/audio_renderer_impl.h
index 20ba1a2..8d8cb3e 100644
--- a/media/renderers/audio_renderer_impl.h
+++ b/media/renderers/audio_renderer_impl.h
@@ -27,6 +27,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/power_monitor/power_observer.h"
 #include "base/synchronization/lock.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "media/base/audio_decoder.h"
@@ -42,7 +43,6 @@
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
-class SingleThreadTaskRunner;
 class TickClock;
 }  // namespace base
 
@@ -75,7 +75,7 @@
   //
   // |decoders| contains the AudioDecoders to use when initializing.
   AudioRendererImpl(
-      const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
+      const scoped_refptr<base::SequencedTaskRunner>& task_runner,
       AudioRendererSink* sink,
       const CreateAudioDecodersCB& create_audio_decoders_cb,
       MediaLog* media_log,
@@ -240,7 +240,7 @@
   void EnableSpeechRecognition();
   void TranscribeAudio(scoped_refptr<media::AudioBuffer> buffer);
 
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+  scoped_refptr<base::SequencedTaskRunner> task_runner_;
 
   std::unique_ptr<AudioBufferConverter> buffer_converter_;
 
diff --git a/media/renderers/decrypting_renderer.cc b/media/renderers/decrypting_renderer.cc
index f79ad19e..2521e57 100644
--- a/media/renderers/decrypting_renderer.cc
+++ b/media/renderers/decrypting_renderer.cc
@@ -19,7 +19,7 @@
 DecryptingRenderer::DecryptingRenderer(
     std::unique_ptr<Renderer> renderer,
     MediaLog* media_log,
-    const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner)
+    const scoped_refptr<base::SequencedTaskRunner> media_task_runner)
     : renderer_(std::move(renderer)),
       media_log_(media_log),
       media_task_runner_(media_task_runner),
@@ -44,7 +44,7 @@
 void DecryptingRenderer::Initialize(MediaResource* media_resource,
                                     RendererClient* client,
                                     PipelineStatusCallback init_cb) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(media_resource);
   DCHECK(client);
 
@@ -75,7 +75,7 @@
 
 void DecryptingRenderer::SetCdm(CdmContext* cdm_context,
                                 CdmAttachedCB cdm_attached_cb) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   if (cdm_context_) {
     DVLOG(1) << "Switching CDM not supported.";
@@ -155,7 +155,7 @@
 }
 
 void DecryptingRenderer::CreateAndInitializeDecryptingMediaResource() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(init_cb_);
 
   decrypting_media_resource_ = std::make_unique<DecryptingMediaResource>(
@@ -168,7 +168,7 @@
 }
 
 void DecryptingRenderer::InitializeRenderer(bool success) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   if (!success) {
     std::move(init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED);
@@ -185,7 +185,7 @@
 }
 
 bool DecryptingRenderer::HasEncryptedStream() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   for (auto* stream : media_resource_->GetAllStreams()) {
     if ((stream->type() == DemuxerStream::AUDIO &&
@@ -204,7 +204,7 @@
 }
 
 void DecryptingRenderer::OnWaiting(WaitingReason reason) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   client_->OnWaiting(reason);
 }
 
diff --git a/media/renderers/decrypting_renderer.h b/media/renderers/decrypting_renderer.h
index ac1fee5..e900b1e 100644
--- a/media/renderers/decrypting_renderer.h
+++ b/media/renderers/decrypting_renderer.h
@@ -38,7 +38,7 @@
   DecryptingRenderer(
       std::unique_ptr<Renderer> renderer,
       MediaLog* media_log,
-      const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner);
+      const scoped_refptr<base::SequencedTaskRunner> media_task_runner);
 
   DecryptingRenderer(const DecryptingRenderer&) = delete;
   DecryptingRenderer& operator=(const DecryptingRenderer&) = delete;
@@ -83,8 +83,7 @@
 
   const std::unique_ptr<Renderer> renderer_;
   const raw_ptr<MediaLog> media_log_;
-  const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
-
+  const scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
   bool waiting_for_cdm_ = false;
   raw_ptr<CdmContext> cdm_context_ = nullptr;
   raw_ptr<RendererClient> client_;
diff --git a/media/renderers/decrypting_renderer_factory.cc b/media/renderers/decrypting_renderer_factory.cc
index 8b38603..e235efbd4 100644
--- a/media/renderers/decrypting_renderer_factory.cc
+++ b/media/renderers/decrypting_renderer_factory.cc
@@ -17,7 +17,7 @@
 DecryptingRendererFactory::~DecryptingRendererFactory() = default;
 
 std::unique_ptr<Renderer> DecryptingRendererFactory::CreateRenderer(
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
     const scoped_refptr<base::TaskRunner>& worker_task_runner,
     AudioRendererSink* audio_renderer_sink,
     VideoRendererSink* video_renderer_sink,
diff --git a/media/renderers/decrypting_renderer_factory.h b/media/renderers/decrypting_renderer_factory.h
index c7a2eb0..9b44894 100644
--- a/media/renderers/decrypting_renderer_factory.h
+++ b/media/renderers/decrypting_renderer_factory.h
@@ -35,7 +35,7 @@
 
   // RendererFactory implementation.
   std::unique_ptr<Renderer> CreateRenderer(
-      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+      const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
       const scoped_refptr<base::TaskRunner>& worker_task_runner,
       AudioRendererSink* audio_renderer_sink,
       VideoRendererSink* video_renderer_sink,
diff --git a/media/renderers/default_renderer_factory.cc b/media/renderers/default_renderer_factory.cc
index 62ff51b..1d68575 100644
--- a/media/renderers/default_renderer_factory.cc
+++ b/media/renderers/default_renderer_factory.cc
@@ -51,7 +51,7 @@
 
 std::vector<std::unique_ptr<AudioDecoder>>
 DefaultRendererFactory::CreateAudioDecoders(
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner) {
+    const scoped_refptr<base::SequencedTaskRunner>& media_task_runner) {
   // Create our audio decoders and renderer.
   std::vector<std::unique_ptr<AudioDecoder>> audio_decoders;
 
@@ -62,7 +62,7 @@
 
 std::vector<std::unique_ptr<VideoDecoder>>
 DefaultRendererFactory::CreateVideoDecoders(
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
     RequestOverlayInfoCB request_overlay_info_cb,
     const gfx::ColorSpace& target_color_space,
     GpuVideoAcceleratorFactories* gpu_factories) {
@@ -77,7 +77,7 @@
 }
 
 std::unique_ptr<Renderer> DefaultRendererFactory::CreateRenderer(
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
     const scoped_refptr<base::TaskRunner>& worker_task_runner,
     AudioRendererSink* audio_renderer_sink,
     VideoRendererSink* video_renderer_sink,
diff --git a/media/renderers/default_renderer_factory.h b/media/renderers/default_renderer_factory.h
index 552fef31..bf2ba60 100644
--- a/media/renderers/default_renderer_factory.h
+++ b/media/renderers/default_renderer_factory.h
@@ -10,6 +10,7 @@
 
 #include "base/callback.h"
 #include "base/memory/raw_ptr.h"
+#include "base/task/sequenced_task_runner.h"
 #include "build/build_config.h"
 #include "media/base/media_export.h"
 #include "media/base/media_player_logging_id.h"
@@ -61,7 +62,7 @@
   ~DefaultRendererFactory() final;
 
   std::unique_ptr<Renderer> CreateRenderer(
-      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+      const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
       const scoped_refptr<base::TaskRunner>& worker_task_runner,
       AudioRendererSink* audio_renderer_sink,
       VideoRendererSink* video_renderer_sink,
@@ -70,9 +71,9 @@
 
  private:
   std::vector<std::unique_ptr<AudioDecoder>> CreateAudioDecoders(
-      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner);
+      const scoped_refptr<base::SequencedTaskRunner>& media_task_runner);
   std::vector<std::unique_ptr<VideoDecoder>> CreateVideoDecoders(
-      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+      const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
       RequestOverlayInfoCB request_overlay_info_cb,
       const gfx::ColorSpace& target_color_space,
       GpuVideoAcceleratorFactories* gpu_factories);
diff --git a/media/renderers/paint_canvas_video_renderer_unittest.cc b/media/renderers/paint_canvas_video_renderer_unittest.cc
index 1014e087..9552432 100644
--- a/media/renderers/paint_canvas_video_renderer_unittest.cc
+++ b/media/renderers/paint_canvas_video_renderer_unittest.cc
@@ -905,7 +905,7 @@
 // unable to wrap a video frame texture (eg due to being abandoned).
 TEST_F(PaintCanvasVideoRendererTest, ContextLost) {
   auto context_provider = viz::TestContextProvider::Create();
-  context_provider->BindToCurrentThread();
+  context_provider->BindToCurrentSequence();
   context_provider->GrContext()->abandonContext();
 
   cc::SkiaPaintCanvas canvas(AllocBitmap(kWidth, kHeight));
@@ -1053,18 +1053,18 @@
     enable_pixels_.emplace();
     media_context_ = base::MakeRefCounted<viz::TestInProcessContextProvider>(
         viz::TestContextType::kGpuRaster, /*support_locking=*/false);
-    gpu::ContextResult result = media_context_->BindToCurrentThread();
+    gpu::ContextResult result = media_context_->BindToCurrentSequence();
     ASSERT_EQ(result, gpu::ContextResult::kSuccess);
 
     gles2_context_ = base::MakeRefCounted<viz::TestInProcessContextProvider>(
         viz::TestContextType::kGLES2, /*support_locking=*/false);
-    result = gles2_context_->BindToCurrentThread();
+    result = gles2_context_->BindToCurrentSequence();
     ASSERT_EQ(result, gpu::ContextResult::kSuccess);
 
     destination_context_ =
         base::MakeRefCounted<viz::TestInProcessContextProvider>(
             viz::TestContextType::kGLES2, /*support_locking=*/false);
-    result = destination_context_->BindToCurrentThread();
+    result = destination_context_->BindToCurrentSequence();
     ASSERT_EQ(result, gpu::ContextResult::kSuccess);
     cropped_frame_ = CreateCroppedFrame();
   }
diff --git a/media/renderers/renderer_impl.cc b/media/renderers/renderer_impl.cc
index 52fa66e..8cff5e8 100644
--- a/media/renderers/renderer_impl.cc
+++ b/media/renderers/renderer_impl.cc
@@ -85,7 +85,7 @@
 };
 
 RendererImpl::RendererImpl(
-    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& task_runner,
     std::unique_ptr<AudioRenderer> audio_renderer,
     std::unique_ptr<VideoRenderer> video_renderer)
     : state_(STATE_UNINITIALIZED),
@@ -114,7 +114,7 @@
 
 RendererImpl::~RendererImpl() {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   // RendererImpl is being destroyed, so invalidate weak pointers right away to
   // avoid getting callbacks which might try to access fields that has been
@@ -136,7 +136,7 @@
                               RendererClient* client,
                               PipelineStatusCallback init_cb) {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK_EQ(state_, STATE_UNINITIALIZED);
   DCHECK(init_cb);
   DCHECK(client);
@@ -161,7 +161,7 @@
 void RendererImpl::SetCdm(CdmContext* cdm_context,
                           CdmAttachedCB cdm_attached_cb) {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(cdm_context);
   TRACE_EVENT0("media", "RendererImpl::SetCdm");
 
@@ -186,7 +186,7 @@
     absl::optional<base::TimeDelta> latency_hint) {
   DVLOG(1) << __func__;
   DCHECK(!latency_hint || (*latency_hint >= base::TimeDelta()));
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   if (video_renderer_)
     video_renderer_->SetLatencyHint(latency_hint);
@@ -197,7 +197,7 @@
 
 void RendererImpl::SetPreservesPitch(bool preserves_pitch) {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   if (audio_renderer_)
     audio_renderer_->SetPreservesPitch(preserves_pitch);
@@ -206,7 +206,7 @@
 void RendererImpl::SetWasPlayedWithUserActivation(
     bool was_played_with_user_activation) {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   if (audio_renderer_)
     audio_renderer_->SetWasPlayedWithUserActivation(
@@ -215,7 +215,7 @@
 
 void RendererImpl::Flush(base::OnceClosure flush_cb) {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(!flush_cb_);
   DCHECK(!(pending_audio_track_change_ || pending_video_track_change_));
   TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("media", "RendererImpl::Flush",
@@ -242,7 +242,7 @@
 
 void RendererImpl::StartPlayingFrom(base::TimeDelta time) {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   TRACE_EVENT1("media", "RendererImpl::StartPlayingFrom", "time_us",
                time.InMicroseconds());
 
@@ -266,7 +266,7 @@
 
 void RendererImpl::SetPlaybackRate(double playback_rate) {
   DVLOG(1) << __func__ << "(" << playback_rate << ")";
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   TRACE_EVENT1("media", "RendererImpl::SetPlaybackRate", "rate", playback_rate);
 
   // Playback rate changes are only carried out while playing.
@@ -288,7 +288,7 @@
 
 void RendererImpl::SetVolume(float volume) {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   if (audio_renderer_)
     audio_renderer_->SetVolume(volume);
@@ -310,7 +310,7 @@
 
 void RendererImpl::DisableUnderflowForTesting() {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK_EQ(state_, STATE_UNINITIALIZED);
 
   underflow_disabled_for_testing_ = true;
@@ -318,7 +318,7 @@
 
 void RendererImpl::EnableClocklessVideoPlaybackForTesting() {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK_EQ(state_, STATE_UNINITIALIZED);
   DCHECK(underflow_disabled_for_testing_)
       << "Underflow must be disabled for clockless video playback";
@@ -383,7 +383,7 @@
 
 void RendererImpl::InitializeAudioRenderer() {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK_EQ(state_, STATE_INITIALIZING);
   DCHECK(init_cb_);
 
@@ -413,7 +413,7 @@
 
 void RendererImpl::OnAudioRendererInitializeDone(PipelineStatus status) {
   DVLOG(1) << __func__ << ": " << status;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   // OnError() may be fired at any time by the renderers, even if they thought
   // they initialized successfully (due to delayed output device setup).
@@ -434,7 +434,7 @@
 
 void RendererImpl::InitializeVideoRenderer() {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK_EQ(state_, STATE_INITIALIZING);
   DCHECK(init_cb_);
 
@@ -464,7 +464,7 @@
 
 void RendererImpl::OnVideoRendererInitializeDone(PipelineStatus status) {
   DVLOG(1) << __func__ << ": " << status;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   // OnError() may be fired at any time by the renderers, even if they thought
   // they initialized successfully (due to delayed output device setup).
@@ -498,7 +498,7 @@
 
 void RendererImpl::FlushInternal() {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK_EQ(state_, STATE_FLUSHING);
   DCHECK(flush_cb_);
 
@@ -511,7 +511,7 @@
 // TODO(tmathmeyer) Combine this functionality with track switching flushing.
 void RendererImpl::FlushAudioRenderer() {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK_EQ(state_, STATE_FLUSHING);
   DCHECK(flush_cb_);
 
@@ -525,7 +525,7 @@
 
 void RendererImpl::OnAudioRendererFlushDone() {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   if (state_ == STATE_ERROR) {
     DCHECK(!flush_cb_);
@@ -547,7 +547,7 @@
 
 void RendererImpl::FlushVideoRenderer() {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK_EQ(state_, STATE_FLUSHING);
   DCHECK(flush_cb_);
 
@@ -561,7 +561,7 @@
 
 void RendererImpl::OnVideoRendererFlushDone() {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   if (state_ == STATE_ERROR) {
     DCHECK(!flush_cb_);
@@ -583,7 +583,7 @@
     base::TimeDelta time,
     base::OnceClosure reinitialize_completed_cb) {
   DVLOG(2) << __func__ << " stream=" << stream << " time=" << time.InSecondsF();
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK_NE(stream, current_audio_stream_);
 
   current_audio_stream_ = stream;
@@ -614,7 +614,7 @@
     base::TimeDelta time,
     base::OnceClosure reinitialize_completed_cb) {
   DVLOG(2) << __func__ << " stream=" << stream << " time=" << time.InSecondsF();
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK_NE(stream, current_video_stream_);
 
   current_video_stream_ = stream;
@@ -648,7 +648,7 @@
     base::TimeDelta time,
     base::OnceClosure restart_completed_cb) {
   DVLOG(2) << __func__ << " stream=" << stream << " time=" << time.InSecondsF();
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(audio_renderer_);
   DCHECK_EQ(stream, current_audio_stream_);
   DCHECK(state_ == STATE_PLAYING || state_ == STATE_FLUSHED ||
@@ -675,7 +675,7 @@
     base::TimeDelta time,
     base::OnceClosure restart_completed_cb) {
   DVLOG(2) << __func__ << " stream=" << stream << " time=" << time.InSecondsF();
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(video_renderer_);
   DCHECK_EQ(stream, current_video_stream_);
   DCHECK(state_ == STATE_PLAYING || state_ == STATE_FLUSHED ||
@@ -695,7 +695,7 @@
 }
 
 void RendererImpl::OnStatisticsUpdate(const PipelineStatistics& stats) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   client_->OnStatisticsUpdate(stats);
 }
 
@@ -711,7 +711,7 @@
   DVLOG(1) << __func__ << " " << type_string << " "
            << BufferingStateToString(*buffering_state) << " -> "
            << BufferingStateToString(new_buffering_state, reason);
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   TRACE_EVENT2("media", "RendererImpl::OnBufferingStateChange", "type",
                type_string, "state",
                BufferingStateToString(new_buffering_state, reason));
@@ -793,7 +793,7 @@
 }
 
 bool RendererImpl::WaitingForEnoughData() const {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   if (state_ != STATE_PLAYING)
     return false;
   if (audio_renderer_ && audio_buffering_state_ != BUFFERING_HAVE_ENOUGH)
@@ -805,7 +805,7 @@
 
 void RendererImpl::PausePlayback() {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   TRACE_EVENT0("media", "RendererImpl::PausePlayback");
 
   switch (state_) {
@@ -843,7 +843,7 @@
 
 void RendererImpl::StartPlayback() {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK_EQ(state_, STATE_PLAYING);
   DCHECK(!WaitingForEnoughData());
   TRACE_EVENT0("media", "RendererImpl::StartPlayback");
@@ -862,7 +862,7 @@
 void RendererImpl::OnRendererEnded(DemuxerStream::Type type) {
   const auto* type_string = DemuxerStream::GetTypeName(type);
   DVLOG(1) << __func__ << ": " << type_string;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK((type == DemuxerStream::AUDIO) || (type == DemuxerStream::VIDEO));
   TRACE_EVENT1("media", "RendererImpl::OnRendererEnded", "type", type_string);
 
@@ -883,7 +883,7 @@
 }
 
 bool RendererImpl::PlaybackHasEnded() const {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   if (audio_renderer_ && !audio_ended_)
     return false;
@@ -896,7 +896,7 @@
 
 void RendererImpl::RunEndedCallbackIfNeeded() {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   if (!PlaybackHasEnded())
     return;
@@ -913,7 +913,7 @@
 
 void RendererImpl::OnError(PipelineStatus error) {
   DVLOG(1) << __func__ << "(" << error << ")";
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(error != PIPELINE_OK) << "PIPELINE_OK isn't an error!";
   TRACE_EVENT1("media", "RendererImpl::OnError", "error",
                PipelineStatusToString(error));
@@ -940,32 +940,32 @@
 }
 
 void RendererImpl::OnWaiting(WaitingReason reason) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   client_->OnWaiting(reason);
 }
 
 void RendererImpl::OnAudioConfigChange(const AudioDecoderConfig& config) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   client_->OnAudioConfigChange(config);
 }
 
 void RendererImpl::OnVideoConfigChange(const VideoDecoderConfig& config) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   client_->OnVideoConfigChange(config);
 }
 
 void RendererImpl::OnVideoNaturalSizeChange(const gfx::Size& size) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   client_->OnVideoNaturalSizeChange(size);
 }
 
 void RendererImpl::OnVideoOpacityChange(bool opaque) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   client_->OnVideoOpacityChange(opaque);
 }
 
 void RendererImpl::OnVideoFrameRateChange(absl::optional<int> fps) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   client_->OnVideoFrameRateChange(fps);
 }
 
@@ -983,7 +983,7 @@
 void RendererImpl::OnSelectedVideoTracksChanged(
     const std::vector<DemuxerStream*>& enabled_tracks,
     base::OnceClosure change_completed_cb) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   TRACE_EVENT0("media", "RendererImpl::OnSelectedVideoTracksChanged");
 
   DCHECK_LT(enabled_tracks.size(), 2u);
@@ -1016,7 +1016,7 @@
 void RendererImpl::OnEnabledAudioTracksChanged(
     const std::vector<DemuxerStream*>& enabled_tracks,
     base::OnceClosure change_completed_cb) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   TRACE_EVENT0("media", "RendererImpl::OnEnabledAudioTracksChanged");
 
   DCHECK_LT(enabled_tracks.size(), 2u);
diff --git a/media/renderers/renderer_impl.h b/media/renderers/renderer_impl.h
index 2f23bd8..5b4a573b 100644
--- a/media/renderers/renderer_impl.h
+++ b/media/renderers/renderer_impl.h
@@ -13,6 +13,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "base/synchronization/lock.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/time/clock.h"
 #include "base/time/default_tick_clock.h"
 #include "base/time/time.h"
@@ -28,10 +29,6 @@
 #include "media/base/waiting.h"
 #include "ui/gfx/geometry/size.h"
 
-namespace base {
-class SingleThreadTaskRunner;
-}
-
 namespace media {
 
 class AudioRenderer;
@@ -46,7 +43,7 @@
   // provided. All methods except for GetMediaTime() run on the |task_runner|.
   // GetMediaTime() runs on the render main thread because it's part of JS sync
   // API.
-  RendererImpl(const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
+  RendererImpl(const scoped_refptr<base::SequencedTaskRunner>& task_runner,
                std::unique_ptr<AudioRenderer> audio_renderer,
                std::unique_ptr<VideoRenderer> video_renderer);
 
@@ -213,7 +210,7 @@
   State state_;
 
   // Task runner used to execute pipeline tasks.
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+  scoped_refptr<base::SequencedTaskRunner> task_runner_;
 
   raw_ptr<MediaResource> media_resource_;
   raw_ptr<RendererClient> client_;
diff --git a/media/renderers/video_renderer_impl.cc b/media/renderers/video_renderer_impl.cc
index a82fa782..4a0b32e7 100644
--- a/media/renderers/video_renderer_impl.cc
+++ b/media/renderers/video_renderer_impl.cc
@@ -48,7 +48,7 @@
 }  // namespace
 
 VideoRendererImpl::VideoRendererImpl(
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
     VideoRendererSink* sink,
     const CreateVideoDecodersCB& create_video_decoders_cb,
     bool drop_frames,
@@ -82,7 +82,7 @@
 }
 
 VideoRendererImpl::~VideoRendererImpl() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   if (init_cb_)
     FinishInitialization(PIPELINE_ERROR_ABORT);
@@ -96,7 +96,7 @@
 
 void VideoRendererImpl::Flush(base::OnceClosure callback) {
   DVLOG(1) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   if (sink_started_)
     StopSink();
@@ -143,7 +143,7 @@
 
 void VideoRendererImpl::StartPlayingFrom(base::TimeDelta timestamp) {
   DVLOG(1) << __func__ << "(" << timestamp.InMicroseconds() << ")";
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   base::AutoLock auto_lock(lock_);
   DCHECK_EQ(state_, kFlushed);
   DCHECK(!pending_read_);
@@ -163,7 +163,7 @@
     RendererClient* client,
     const TimeSource::WallClockTimeCB& wall_clock_time_cb,
     PipelineStatusCallback init_cb) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("media", "VideoRendererImpl::Initialize",
                                     TRACE_ID_LOCAL(this));
 
@@ -293,7 +293,7 @@
 }
 
 void VideoRendererImpl::OnVideoDecoderStreamInitialized(bool success) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   base::AutoLock auto_lock(lock_);
   DCHECK_EQ(state_, kInitializing);
 
@@ -331,12 +331,12 @@
 }
 
 void VideoRendererImpl::OnPlaybackError(PipelineStatus error) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   client_->OnError(error);
 }
 
 void VideoRendererImpl::OnPlaybackEnded() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   {
     // Send one last stats update so things like memory usage are correct.
     base::AutoLock auto_lock(lock_);
@@ -347,12 +347,12 @@
 }
 
 void VideoRendererImpl::OnStatisticsUpdate(const PipelineStatistics& stats) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   client_->OnStatisticsUpdate(stats);
 }
 
 void VideoRendererImpl::OnBufferingStateChange(BufferingState buffering_state) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   // "Underflow" is only possible when playing. This avoids noise like blaming
   // the decoder for an "underflow" that is really just a seek.
@@ -371,12 +371,12 @@
 }
 
 void VideoRendererImpl::OnWaiting(WaitingReason reason) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   client_->OnWaiting(reason);
 }
 
 void VideoRendererImpl::OnConfigChange(const VideoDecoderConfig& config) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(config.IsValidConfig());
 
   // RendererClient only cares to know about config changes that differ from
@@ -388,7 +388,7 @@
 }
 
 void VideoRendererImpl::OnFallback(PipelineStatus status) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   client_->OnFallback(std::move(status).AddHere());
 }
 
@@ -398,7 +398,7 @@
 }
 
 void VideoRendererImpl::OnTimeProgressing() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   // WARNING: Do not attempt to use |lock_| here as StartSink() may cause a
   // reentrant call.
@@ -424,7 +424,7 @@
 }
 
 void VideoRendererImpl::OnTimeStopped() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   // WARNING: Do not attempt to use |lock_| here as StopSink() may cause a
   // reentrant call.
@@ -564,7 +564,7 @@
 }
 
 void VideoRendererImpl::FrameReady(VideoDecoderStream::ReadResult result) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   base::AutoLock auto_lock(lock_);
   DCHECK_EQ(state_, kPlaying);
   CHECK(pending_read_);
@@ -728,7 +728,7 @@
 
 void VideoRendererImpl::TransitionToHaveEnough_Locked() {
   DVLOG(3) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING);
   lock_.AssertAcquired();
 
@@ -740,7 +740,7 @@
 
 void VideoRendererImpl::TransitionToHaveNothing() {
   DVLOG(3) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   base::AutoLock auto_lock(lock_);
   TransitionToHaveNothing_Locked();
@@ -748,7 +748,7 @@
 
 void VideoRendererImpl::TransitionToHaveNothing_Locked() {
   DVLOG(3) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   lock_.AssertAcquired();
 
   if (buffering_state_ != BUFFERING_HAVE_ENOUGH || HaveEnoughData_Locked())
@@ -761,7 +761,7 @@
 }
 
 void VideoRendererImpl::AddReadyFrame_Locked(scoped_refptr<VideoFrame> frame) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   lock_.AssertAcquired();
   DCHECK(!frame->metadata().end_of_stream);
 
@@ -774,7 +774,7 @@
 }
 
 void VideoRendererImpl::AttemptRead_Locked() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   lock_.AssertAcquired();
 
   if (pending_read_ || received_end_of_stream_)
@@ -801,7 +801,7 @@
 void VideoRendererImpl::OnVideoDecoderStreamResetDone() {
   // We don't need to acquire the |lock_| here, because we can only get here
   // when Flush is in progress, so rendering and video sink must be stopped.
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(!sink_started_);
   DCHECK_EQ(kFlushing, state_);
   DCHECK(!received_end_of_stream_);
@@ -813,7 +813,7 @@
 }
 
 void VideoRendererImpl::UpdateStats_Locked(bool force_update) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   lock_.AssertAcquired();
 
   // No need to check for `stats_.video_frames_decoded_power_efficient` because
@@ -841,7 +841,7 @@
 }
 
 void VideoRendererImpl::ReportFrameRateIfNeeded_Locked() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   lock_.AssertAcquired();
 
   absl::optional<int> current_fps = fps_estimator_.ComputeFPS();
@@ -860,7 +860,7 @@
 }
 
 bool VideoRendererImpl::HaveReachedBufferingCap(size_t buffering_cap) const {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   // When the display rate is less than the frame rate, the effective frames
   // queued may be much smaller than the actual number of frames queued.  Here
@@ -870,7 +870,7 @@
 }
 
 void VideoRendererImpl::StartSink() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK_GT(algorithm_->frames_queued(), 0u);
   sink_started_ = true;
   was_background_rendering_ = false;
@@ -878,7 +878,7 @@
 }
 
 void VideoRendererImpl::StopSink() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
   sink_->Stop();
   algorithm_->set_time_stopped();
   sink_started_ = false;
@@ -1016,7 +1016,7 @@
 
 void VideoRendererImpl::CheckForMetadataChanges(VideoPixelFormat pixel_format,
                                                 const gfx::Size& natural_size) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   // Notify client of size and opacity changes if this is the first frame
   // or if those have changed from the last frame.
diff --git a/media/renderers/video_renderer_impl.h b/media/renderers/video_renderer_impl.h
index 7ef5004..d76c449 100644
--- a/media/renderers/video_renderer_impl.h
+++ b/media/renderers/video_renderer_impl.h
@@ -15,6 +15,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/synchronization/condition_variable.h"
 #include "base/synchronization/lock.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 #include "media/base/decryptor.h"
@@ -35,7 +36,6 @@
 #include "media/video/gpu_memory_buffer_video_frame_pool.h"
 
 namespace base {
-class SingleThreadTaskRunner;
 class TickClock;
 }  // namespace base
 
@@ -56,7 +56,7 @@
   //
   // Setting |drop_frames_| to true causes the renderer to drop expired frames.
   VideoRendererImpl(
-      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+      const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
       VideoRendererSink* sink,
       const CreateVideoDecodersCB& create_video_decoders_cb,
       bool drop_frames,
@@ -209,7 +209,7 @@
   void AttemptReadAndCheckForMetadataChanges(VideoPixelFormat pixel_format,
                                              const gfx::Size& natural_size);
 
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+  scoped_refptr<base::SequencedTaskRunner> task_runner_;
 
   // Sink which calls into VideoRendererImpl via Render() for video frames.  Do
   // not call any methods on the sink while |lock_| is held or the two threads
diff --git a/media/renderers/video_resource_updater_unittest.cc b/media/renderers/video_resource_updater_unittest.cc
index 5c47a89..ecc13b2 100644
--- a/media/renderers/video_resource_updater_unittest.cc
+++ b/media/renderers/video_resource_updater_unittest.cc
@@ -76,7 +76,7 @@
     gl_ = gl.get();
 
     context_provider_ = viz::TestContextProvider::Create(std::move(gl));
-    context_provider_->BindToCurrentThread();
+    context_provider_->BindToCurrentSequence();
   }
 
   // testing::Test implementation.
diff --git a/media/video/gpu_memory_buffer_video_frame_pool.cc b/media/video/gpu_memory_buffer_video_frame_pool.cc
index 098650d..b8506c4f 100644
--- a/media/video/gpu_memory_buffer_video_frame_pool.cc
+++ b/media/video/gpu_memory_buffer_video_frame_pool.cc
@@ -28,6 +28,7 @@
 #include "base/ranges/algorithm.h"
 #include "base/strings/stringprintf.h"
 #include "base/sys_byteorder.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/time/default_tick_clock.h"
 #include "base/time/time.h"
 #include "base/trace_event/memory_dump_manager.h"
@@ -79,7 +80,7 @@
   // video frame's planes.
   // |gpu_factories| is an interface to GPU related operation and can be
   // null if a GL context is not available.
-  PoolImpl(const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+  PoolImpl(const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
            const scoped_refptr<base::TaskRunner>& worker_task_runner,
            GpuVideoAcceleratorFactories* const gpu_factories)
       : media_task_runner_(media_task_runner),
@@ -249,7 +250,7 @@
       FrameResources* frame_resources);
 
   // Task runner associated to the GL context provided by |gpu_factories_|.
-  const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+  const scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
   // Task runner used to asynchronously copy planes.
   const scoped_refptr<base::TaskRunner> worker_task_runner_;
 
@@ -718,7 +719,7 @@
 void GpuMemoryBufferVideoFramePool::PoolImpl::CreateHardwareFrame(
     scoped_refptr<VideoFrame> video_frame,
     FrameReadyCB frame_ready_cb) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   // Lazily initialize |output_format_| since VideoFrameOutputFormat() has to be
   // called on the media_thread while this object might be instantiated on any.
   const VideoPixelFormat pixel_format = video_frame->format();
@@ -855,7 +856,7 @@
 }
 
 void GpuMemoryBufferVideoFramePool::PoolImpl::Abort() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   // Abort any pending copy requests. If one is already in flight, we can't do
   // anything about it.
   if (frame_copy_requests_.size() <= 1u)
@@ -890,7 +891,7 @@
 }
 
 void GpuMemoryBufferVideoFramePool::PoolImpl::StartCopy() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(!frame_copy_requests_.empty());
 
   while (!frame_copy_requests_.empty()) {
@@ -1088,7 +1089,7 @@
     bool copy_failed,
     scoped_refptr<VideoFrame> video_frame,
     FrameResources* frame_resources) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   if (copy_failed) {
     // Drop the resources if there was an error with them. If we're not in
     // shutdown we also need to remove the pool entry for them.
@@ -1135,7 +1136,7 @@
         const gfx::ColorSpace& color_space,
         base::TimeDelta timestamp,
         bool allow_i420_overlay) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   gpu::SharedImageInterface* sii = gpu_factories_->SharedImageInterface();
   if (!sii) {
     frame_resources->MarkUnused(tick_clock_->NowTicks());
@@ -1275,7 +1276,7 @@
 }
 
 void GpuMemoryBufferVideoFramePool::PoolImpl::Shutdown() {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   // Clients don't care about copies once shutdown has started, so abort them.
   Abort();
 
@@ -1306,7 +1307,7 @@
     const gfx::Size& size,
     GpuVideoAcceleratorFactories::OutputFormat format,
     gfx::BufferUsage usage) {
-  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
   auto it = resources_pool_.begin();
   while (it != resources_pool_.end()) {
@@ -1379,7 +1380,7 @@
 void GpuMemoryBufferVideoFramePool::PoolImpl::MailboxHoldersReleased(
     FrameResources* frame_resources,
     const gpu::SyncToken& release_sync_token) {
-  if (!media_task_runner_->BelongsToCurrentThread()) {
+  if (!media_task_runner_->RunsTasksInCurrentSequence()) {
     media_task_runner_->PostTask(
         FROM_HERE, base::BindOnce(&PoolImpl::MailboxHoldersReleased, this,
                                   frame_resources, release_sync_token));
@@ -1414,13 +1415,15 @@
 GpuMemoryBufferVideoFramePool::GpuMemoryBufferVideoFramePool() = default;
 
 GpuMemoryBufferVideoFramePool::GpuMemoryBufferVideoFramePool(
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
     const scoped_refptr<base::TaskRunner>& worker_task_runner,
     GpuVideoAcceleratorFactories* gpu_factories)
     : pool_impl_(
           new PoolImpl(media_task_runner, worker_task_runner, gpu_factories)) {
-  base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-      pool_impl_.get(), "GpuMemoryBufferVideoFramePool", media_task_runner);
+  base::trace_event::MemoryDumpManager::GetInstance()
+      ->RegisterDumpProviderWithSequencedTaskRunner(
+          pool_impl_.get(), "GpuMemoryBufferVideoFramePool", media_task_runner,
+          base::trace_event::MemoryDumpProvider::Options());
 }
 
 GpuMemoryBufferVideoFramePool::~GpuMemoryBufferVideoFramePool() {
diff --git a/media/video/gpu_memory_buffer_video_frame_pool.h b/media/video/gpu_memory_buffer_video_frame_pool.h
index d7bfd31..c6378dd0 100644
--- a/media/video/gpu_memory_buffer_video_frame_pool.h
+++ b/media/video/gpu_memory_buffer_video_frame_pool.h
@@ -6,11 +6,11 @@
 #define MEDIA_VIDEO_GPU_MEMORY_BUFFER_VIDEO_FRAME_POOL_H_
 
 #include "base/memory/ref_counted.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/task/task_runner.h"
 #include "media/base/video_frame.h"
 
 namespace base {
-class SingleThreadTaskRunner;
 class TickClock;
 }
 
@@ -34,7 +34,7 @@
  public:
   GpuMemoryBufferVideoFramePool();
   GpuMemoryBufferVideoFramePool(
-      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+      const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
       const scoped_refptr<base::TaskRunner>& worker_task_runner,
       GpuVideoAcceleratorFactories* gpu_factories);
 
diff --git a/mojo/public/cpp/bindings/lib/wtf_hash_util.h b/mojo/public/cpp/bindings/lib/wtf_hash_util.h
index 72a5e6d..63a20a2 100644
--- a/mojo/public/cpp/bindings/lib/wtf_hash_util.h
+++ b/mojo/public/cpp/bindings/lib/wtf_hash_util.h
@@ -57,29 +57,6 @@
   return WTFHashTraits<T>::Hash(seed, value);
 }
 
-template <typename T>
-struct StructPtrHashFn {
-  static unsigned GetHash(const StructPtr<T>& value) {
-    return static_cast<unsigned>(value.Hash(kHashSeed));
-  }
-  static bool Equal(const StructPtr<T>& left, const StructPtr<T>& right) {
-    return left.Equals(right);
-  }
-  static const bool safe_to_compare_to_empty_or_deleted = false;
-};
-
-template <typename T>
-struct InlinedStructPtrHashFn {
-  static unsigned GetHash(const InlinedStructPtr<T>& value) {
-    return static_cast<unsigned>(value.Hash(kHashSeed));
-  }
-  static bool Equal(const InlinedStructPtr<T>& left,
-                    const InlinedStructPtr<T>& right) {
-    return left.Equals(right);
-  }
-  static const bool safe_to_compare_to_empty_or_deleted = false;
-};
-
 }  // namespace internal
 }  // namespace mojo
 
@@ -87,7 +64,14 @@
 
 template <typename T>
 struct DefaultHash<mojo::StructPtr<T>> {
-  using Hash = mojo::internal::StructPtrHashFn<T>;
+  static unsigned GetHash(const mojo::StructPtr<T>& value) {
+    return static_cast<unsigned>(value.Hash(mojo::internal::kHashSeed));
+  }
+  static bool Equal(const mojo::StructPtr<T>& left,
+                    const mojo::StructPtr<T>& right) {
+    return left.Equals(right);
+  }
+  static const bool safe_to_compare_to_empty_or_deleted = false;
 };
 
 template <typename T>
@@ -108,7 +92,14 @@
 
 template <typename T>
 struct DefaultHash<mojo::InlinedStructPtr<T>> {
-  using Hash = mojo::internal::InlinedStructPtrHashFn<T>;
+  static unsigned GetHash(const mojo::InlinedStructPtr<T>& value) {
+    return static_cast<unsigned>(value.Hash(mojo::internal::kHashSeed));
+  }
+  static bool Equal(const mojo::InlinedStructPtr<T>& left,
+                    const mojo::InlinedStructPtr<T>& right) {
+    return left.Equals(right);
+  }
+  static const bool safe_to_compare_to_empty_or_deleted = false;
 };
 
 template <typename T>
diff --git a/mojo/public/cpp/bindings/tests/wtf_hash_unittest.cc b/mojo/public/cpp/bindings/tests/wtf_hash_unittest.cc
index 4484673..81c3552 100644
--- a/mojo/public/cpp/bindings/tests/wtf_hash_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/wtf_hash_unittest.cc
@@ -29,21 +29,20 @@
   // Just check that this template instantiation compiles.
 
   // Top-level.
-  ASSERT_EQ(WTF::DefaultHash<blink::TopLevelEnum>::Hash().GetHash(
-                blink::TopLevelEnum::E0),
-            WTF::DefaultHash<blink::TopLevelEnum>::Hash().GetHash(
-                blink::TopLevelEnum::E0));
+  ASSERT_EQ(
+      WTF::DefaultHash<blink::TopLevelEnum>::GetHash(blink::TopLevelEnum::E0),
+      WTF::DefaultHash<blink::TopLevelEnum>::GetHash(blink::TopLevelEnum::E0));
 
   // Nested in struct.
-  ASSERT_EQ(WTF::DefaultHash<blink::TestWTFStruct::NestedEnum>::Hash().GetHash(
+  ASSERT_EQ(WTF::DefaultHash<blink::TestWTFStruct::NestedEnum>::GetHash(
                 blink::TestWTFStruct::NestedEnum::E0),
-            WTF::DefaultHash<blink::TestWTFStruct::NestedEnum>::Hash().GetHash(
+            WTF::DefaultHash<blink::TestWTFStruct::NestedEnum>::GetHash(
                 blink::TestWTFStruct::NestedEnum::E0));
 
   // Nested in interface.
-  ASSERT_EQ(WTF::DefaultHash<blink::TestWTF::NestedEnum>::Hash().GetHash(
+  ASSERT_EQ(WTF::DefaultHash<blink::TestWTF::NestedEnum>::GetHash(
                 blink::TestWTF::NestedEnum::E0),
-            WTF::DefaultHash<blink::TestWTF::NestedEnum>::Hash().GetHash(
+            WTF::DefaultHash<blink::TestWTF::NestedEnum>::GetHash(
                 blink::TestWTF::NestedEnum::E0));
 }
 
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl
index 27a38dff..537ff35 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl
@@ -146,7 +146,7 @@
 struct {{hash_fn_name}} {
   static unsigned GetHash(const {{enum_name}}& value) {
     using utype = std::underlying_type<{{enum_name}}>::type;
-    return DefaultHash<utype>::Hash().GetHash(static_cast<utype>(value));
+    return DefaultHash<utype>::GetHash(static_cast<utype>(value));
   }
   static bool Equal(const {{enum_name}}& left, const {{enum_name}}& right) {
     return left == right;
diff --git a/net/quic/mock_crypto_client_stream.cc b/net/quic/mock_crypto_client_stream.cc
index 4475530..eca4e810 100644
--- a/net/quic/mock_crypto_client_stream.cc
+++ b/net/quic/mock_crypto_client_stream.cc
@@ -34,7 +34,6 @@
 using quic::kQBIC;
 using quic::NullDecrypter;
 using quic::NullEncrypter;
-using quic::PACKET_8BYTE_CONNECTION_ID;
 using quic::Perspective;
 using quic::ProofVerifyContext;
 using quic::QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE;
@@ -53,6 +52,11 @@
 using std::string;
 
 namespace net {
+namespace {
+
+static constexpr int k8ByteConnectionId = 8;
+
+}  // namespace
 
 MockCryptoClientStream::MockCryptoClientStream(
     const QuicServerId& server_id,
@@ -365,7 +369,7 @@
 #endif
   cgst.push_back(kQBIC);
   QuicConfig config(config_);
-  config.SetBytesForConnectionIdToSend(PACKET_8BYTE_CONNECTION_ID);
+  config.SetBytesForConnectionIdToSend(k8ByteConnectionId);
   config.SetMaxBidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection / 2);
   config.SetMaxUnidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection / 2);
   config.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
diff --git a/net/quic/quic_proxy_client_socket_unittest.cc b/net/quic/quic_proxy_client_socket_unittest.cc
index db797f5..4be2356 100644
--- a/net/quic/quic_proxy_client_socket_unittest.cc
+++ b/net/quic/quic_proxy_client_socket_unittest.cc
@@ -92,6 +92,9 @@
 static const char kMsg333[] = "bye!bye!bye!";
 static const int kLen333 = kLen3 + kLen3 + kLen3;
 
+static constexpr int k0ByteConnectionId = 0;
+static constexpr int k8ByteConnectionId = 8;
+
 struct TestParams {
   quic::ParsedQuicVersion version;
   bool client_headers_include_h2_stream_dependency;
@@ -130,7 +133,7 @@
       quic::ParsedQuicVersion version,
       bool include_version,
       bool include_diversification_nonce,
-      quic::QuicConnectionIdLength connection_id_length,
+      int connection_id_length,
       quic::QuicPacketNumberLength packet_number_length,
       quic::QuicStreamOffset offset) {
     quiche::QuicheVariableLengthIntegerLength retry_token_length_length =
@@ -145,10 +148,10 @@
         quic::NullEncrypter(quic::Perspective::IS_CLIENT)
             .GetCiphertextSize(min_data_length) +
         quic::QuicPacketCreator::StreamFramePacketOverhead(
-            version.transport_version, quic::PACKET_8BYTE_CONNECTION_ID,
-            quic::PACKET_0BYTE_CONNECTION_ID, include_version,
-            include_diversification_nonce, packet_number_length,
-            retry_token_length_length, length_length, offset);
+            version.transport_version, k8ByteConnectionId, k0ByteConnectionId,
+            include_version, include_diversification_nonce,
+            packet_number_length, retry_token_length_length, length_length,
+            offset);
 
     DCHECK(packet_length >= min_packet_length);
     return min_data_length + packet_length - min_packet_length;
@@ -1095,7 +1098,7 @@
   for (int i = 0; i < numDataPackets; ++i) {
     size_t max_packet_data_length = GetStreamFrameDataLengthFromPacketLength(
         quic::kDefaultMaxPacketSize, version_, !kIncludeVersion,
-        !kIncludeDiversificationNonce, quic::PACKET_8BYTE_CONNECTION_ID,
+        !kIncludeDiversificationNonce, k8ByteConnectionId,
         quic::PACKET_1BYTE_PACKET_NUMBER, offset);
     if (version_.HasIetfQuicFrames() && i == 0) {
       // 3673 is the data frame length from packet length.
diff --git a/services/network/public/cpp/content_security_policy/OWNERS b/services/network/public/cpp/content_security_policy/OWNERS
index af7f6c9..1245fcd 100644
--- a/services/network/public/cpp/content_security_policy/OWNERS
+++ b/services/network/public/cpp/content_security_policy/OWNERS
@@ -1,2 +1,2 @@
+antoniosartori@chromium.org
 arthursonzogni@chromium.org
-mkwst@chromium.org
diff --git a/services/viz/public/cpp/gpu/context_provider_command_buffer.cc b/services/viz/public/cpp/gpu/context_provider_command_buffer.cc
index e26a4dd..6e540657 100644
--- a/services/viz/public/cpp/gpu/context_provider_command_buffer.cc
+++ b/services/viz/public/cpp/gpu/context_provider_command_buffer.cc
@@ -19,8 +19,10 @@
 #include "base/no_destructor.h"
 #include "base/observer_list.h"
 #include "base/strings/stringprintf.h"
+#include "base/threading/sequenced_task_runner_handle.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/trace_event/memory_dump_manager.h"
+#include "base/trace_event/memory_dump_provider.h"
 #include "build/build_config.h"
 #include "components/viz/common/gpu/context_cache_controller.h"
 #include "gpu/command_buffer/client/gles2_cmd_helper.h"
@@ -84,11 +86,11 @@
       buffer_mapper_(buffer_mapper) {
   DCHECK(main_thread_checker_.CalledOnValidThread());
   DCHECK(channel_);
-  context_thread_checker_.DetachFromThread();
+  context_sequence_checker_.DetachFromSequence();
 }
 
 ContextProviderCommandBuffer::~ContextProviderCommandBuffer() {
-  DCHECK(context_thread_checker_.CalledOnValidThread());
+  DCHECK(context_sequence_checker_.CalledOnValidSequence());
 
   if (bind_tried_ && bind_result_ == gpu::ContextResult::kSuccess) {
     // Clear the lock to avoid DCHECKs that the lock is being held during
@@ -124,9 +126,9 @@
   base::RefCountedThreadSafe<ContextProviderCommandBuffer>::Release();
 }
 
-gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentThread() {
+gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentSequence() {
   // This is called on the thread the context will be used.
-  DCHECK(context_thread_checker_.CalledOnValidThread());
+  DCHECK(context_sequence_checker_.CalledOnValidSequence());
 
   if (bind_tried_)
     return bind_result_;
@@ -135,11 +137,9 @@
   // Any early-out should set this to a failure code and return it.
   bind_result_ = gpu::ContextResult::kSuccess;
 
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner =
-      default_task_runner_;
+  scoped_refptr<base::SequencedTaskRunner> task_runner = default_task_runner_;
   if (!task_runner)
-    task_runner = base::ThreadTaskRunnerHandle::Get();
-
+    task_runner = base::SequencedTaskRunnerHandle::Get();
   // This command buffer is a client-side proxy to the command buffer in the
   // GPU process.
   command_buffer_ = std::make_unique<gpu::CommandBufferProxyImpl>(
@@ -337,15 +337,17 @@
   shared_image_interface_ = channel_->CreateClientSharedImageInterface();
   DCHECK(shared_image_interface_);
 
-  base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-      this, "ContextProviderCommandBuffer", std::move(task_runner));
+  base::trace_event::MemoryDumpManager::GetInstance()
+      ->RegisterDumpProviderWithSequencedTaskRunner(
+          this, "ContextProviderCommandBuffer", std::move(task_runner),
+          base::trace_event::MemoryDumpProvider::Options());
   return bind_result_;
 }
 
 gpu::gles2::GLES2Interface* ContextProviderCommandBuffer::ContextGL() {
   DCHECK(bind_tried_);
   DCHECK_EQ(bind_result_, gpu::ContextResult::kSuccess);
-  CheckValidThreadOrLockAcquired();
+  CheckValidSequenceOrLockAcquired();
 
   if (!attributes_.enable_gles2_interface)
     return nullptr;
@@ -358,7 +360,7 @@
 gpu::raster::RasterInterface* ContextProviderCommandBuffer::RasterInterface() {
   DCHECK(bind_tried_);
   DCHECK_EQ(bind_result_, gpu::ContextResult::kSuccess);
-  CheckValidThreadOrLockAcquired();
+  CheckValidSequenceOrLockAcquired();
 
   if (raster_interface_)
     return raster_interface_.get();
@@ -384,7 +386,7 @@
   DCHECK_EQ(bind_result_, gpu::ContextResult::kSuccess);
   if (!support_grcontext_ || !ContextSupport()->HasGrContextSupport())
     return nullptr;
-  CheckValidThreadOrLockAcquired();
+  CheckValidSequenceOrLockAcquired();
 
   if (gr_context_)
     return gr_context_->get();
@@ -442,7 +444,7 @@
 }
 
 ContextCacheController* ContextProviderCommandBuffer::CacheController() {
-  CheckValidThreadOrLockAcquired();
+  CheckValidSequenceOrLockAcquired();
   return cache_controller_.get();
 }
 
@@ -462,7 +464,7 @@
     const {
   DCHECK(bind_tried_);
   DCHECK_EQ(bind_result_, gpu::ContextResult::kSuccess);
-  CheckValidThreadOrLockAcquired();
+  CheckValidSequenceOrLockAcquired();
   // Skips past the trace_impl_ as it doesn't have capabilities.
   return impl_->capabilities();
 }
@@ -471,7 +473,7 @@
     const {
   DCHECK(bind_tried_);
   DCHECK_EQ(bind_result_, gpu::ContextResult::kSuccess);
-  CheckValidThreadOrLockAcquired();
+  CheckValidSequenceOrLockAcquired();
   if (!command_buffer_ || !command_buffer_->channel()) {
     static const base::NoDestructor<gpu::GpuFeatureInfo>
         default_gpu_feature_info;
@@ -481,7 +483,7 @@
 }
 
 void ContextProviderCommandBuffer::OnLostContext() {
-  CheckValidThreadOrLockAcquired();
+  CheckValidSequenceOrLockAcquired();
 
   // Observers may drop the last persistent references to `this`, but there may
   // be weak references in use further up the stack. This task is posted to
@@ -502,19 +504,19 @@
 }
 
 void ContextProviderCommandBuffer::AddObserver(ContextLostObserver* obs) {
-  CheckValidThreadOrLockAcquired();
+  CheckValidSequenceOrLockAcquired();
   observers_.AddObserver(obs);
 }
 
 void ContextProviderCommandBuffer::RemoveObserver(ContextLostObserver* obs) {
-  CheckValidThreadOrLockAcquired();
+  CheckValidSequenceOrLockAcquired();
   observers_.RemoveObserver(obs);
 }
 
 gpu::webgpu::WebGPUInterface* ContextProviderCommandBuffer::WebGPUInterface() {
   DCHECK(bind_tried_);
   DCHECK_EQ(bind_result_, gpu::ContextResult::kSuccess);
-  CheckValidThreadOrLockAcquired();
+  CheckValidSequenceOrLockAcquired();
 
   return webgpu_interface_.get();
 }
@@ -531,10 +533,10 @@
   helper_->OnMemoryDump(args, pmd);
 
   if (gr_context_) {
-    context_thread_checker_.DetachFromThread();
+    context_sequence_checker_.DetachFromSequence();
     gpu::raster::DumpGrMemoryStatistics(gr_context_->get(), pmd,
                                         gles2_impl_->ShareGroupTracingGUID());
-    context_thread_checker_.DetachFromThread();
+    context_sequence_checker_.DetachFromSequence();
   }
   return true;
 }
diff --git a/services/viz/public/cpp/gpu/context_provider_command_buffer.h b/services/viz/public/cpp/gpu/context_provider_command_buffer.h
index 22b9d09..04de90c5 100644
--- a/services/viz/public/cpp/gpu/context_provider_command_buffer.h
+++ b/services/viz/public/cpp/gpu/context_provider_command_buffer.h
@@ -15,6 +15,7 @@
 #include "base/memory/shared_memory_mapper.h"
 #include "base/observer_list.h"
 #include "base/synchronization/lock.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/threading/thread_checker.h"
 #include "base/trace_event/memory_dump_provider.h"
@@ -91,7 +92,7 @@
   // ContextProvider / RasterContextProvider implementation.
   void AddRef() const override;
   void Release() const override;
-  gpu::ContextResult BindToCurrentThread() override;
+  gpu::ContextResult BindToCurrentSequence() override;
   gpu::gles2::GLES2Interface* ContextGL() override;
   gpu::raster::RasterInterface* RasterInterface() override;
   gpu::ContextSupport* ContextSupport() override;
@@ -123,18 +124,18 @@
   void OnLostContext();
 
  private:
-  void CheckValidThreadOrLockAcquired() const {
+  void CheckValidSequenceOrLockAcquired() const {
 #if DCHECK_IS_ON()
     if (support_locking_) {
       context_lock_.AssertAcquired();
     } else {
-      DCHECK(context_thread_checker_.CalledOnValidThread());
+      DCHECK(context_sequence_checker_.CalledOnValidSequence());
     }
 #endif
   }
 
   base::ThreadChecker main_thread_checker_;
-  base::ThreadChecker context_thread_checker_;
+  base::SequenceChecker context_sequence_checker_;
 
   bool bind_tried_ = false;
   gpu::ContextResult bind_result_;
@@ -153,7 +154,7 @@
   scoped_refptr<gpu::GpuChannelHost> channel_;
   raw_ptr<gpu::GpuMemoryBufferManager, DanglingUntriaged>
       gpu_memory_buffer_manager_;
-  scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
+  scoped_refptr<base::SequencedTaskRunner> default_task_runner_;
 
   // |shared_image_interface_| must be torn down after |command_buffer_| to
   // ensure any dependent commands in the command stream are flushed before the
diff --git a/testing/buildbot/filters/mac.mac12-arm64-rel.browser_tests.filter b/testing/buildbot/filters/mac.mac12-arm64-rel.browser_tests.filter
index a0409ce0..8fa1ffc 100644
--- a/testing/buildbot/filters/mac.mac12-arm64-rel.browser_tests.filter
+++ b/testing/buildbot/filters/mac.mac12-arm64-rel.browser_tests.filter
@@ -12,12 +12,27 @@
 -All/MediaHistoryBrowserTest.DoNotRecordWatchtime_Muted/0
 -All/PageLoadMetricsBackForwardCacheBrowserTest.LogsBasicPageForegroundDuration/BFCacheEnabled
 -All/PageLoadMetricsBackForwardCacheBrowserTest.LogsPageEndReasons/BFCacheEnabled
+-All/SearchPrefetchServiceEnabledBrowserTest.HungRequestCanBeServed/1
 -All/SearchPrefetchServiceEnabledBrowserTest.OmniboxEditTriggersPrefetch/1
+-All/SearchPrefetchServiceEnabledBrowserTest.OmniboxEditTriggersPrefetch/0
 -All/SearchPrefetchServiceEnabledBrowserTest.OmniboxEditTriggersPrefetchForSecondMatch/0
+-All/SearchPrefetchServiceEnabledBrowserTest.OmniboxEditTriggersPrefetchForSecondMatch/1
+-All/SearchPrefetchServiceEnabledBrowserTest.OmniboxNavigateToNonMatchingEntryStreamingCancels/1
+-All/SearchPrefetchServiceEnabledBrowserTest.OmniboxNavigateToMatchingEntryStreaming/1
 -All/SearchPrefetchServiceEnabledBrowserTest.OmniboxURLHasPfParam/0
+-All/SearchPrefetchServiceEnabledBrowserTest.OmniboxURLHasPfParam/1
+-All/SearchPrefetchServiceEnabledBrowserTest.PrefetchFallbackFromError/0
+-All/SearchPrefetchServiceEnabledBrowserTest.PrefetchFallbackSecureSecurityState/0
 -All/SearchPrefetchServiceEnabledBrowserTest.PrefetchRateLimiting/1
+-All/SearchPrefetchServiceEnabledBrowserTest.PrefetchSecureSecurityState/0
 -All/SearchPrefetchServiceEnabledBrowserTest.PrefetchServedBeforeHeaders/0
+-All/SearchPrefetchServiceEnabledBrowserTest.RemovingMatchCancelsInFlight/0
 -All/SearchPrefetchServiceEnabledBrowserTest.RemovingMatchCancelsInFlight/1
+-All/PromotionalTabsEnabledPolicyWhatsNewTest.RunTest/0
+-All/PromotionalTabsEnabledPolicyWhatsNewTest.RunTest/2
+-AccessCodeCastHandlerBrowserTest.ExpectGenericErrorWhenNoSync
+-AccessCodeCastHandlerBrowserTest.ExpectNetworkErrorWhenNoNetwork
+-AccessCodeCastHandlerBrowserTest.ReturnSuccessfulResponse
 -AutomationApiTest.ForceLayout
 -BackForwardCachePageLoadMetricsObserverBrowserTest.CumulativeLayoutShiftAfterBackForwardCacheRestore
 -BackForwardCachePageLoadMetricsObserverBrowserTest.FirstPaintAfterBackForwardCacheRestore
@@ -79,6 +94,8 @@
 -FirstRunMasterPrefsWithTrackedPreferencesInstance/FirstRunMasterPrefsWithTrackedPreferences.TrackedPreferencesSurviveFirstRun/2
 -FirstRunMasterPrefsWithTrackedPreferencesInstance/FirstRunMasterPrefsWithTrackedPreferences.TrackedPreferencesSurviveFirstRun/3
 -FirstRunMasterPrefsVariationsSeedTests/FirstRunMasterPrefsVariationsSeedTest.Test/1
+-FormfillPageLoadMetricsObserverBrowserTest.UserDataFieldFilledPreviouslyUseCounter
+-FormfillPageLoadMetricsObserverBrowserTest.UserDataFieldFilledUseCounter
 -GlobalErrorServiceBrowserTest.BubbleViewDismissedOnRemove
 -HttpsOnlyModeBrowserTest.BadHttpsFollowedByGoodHttps
 -IdleServiceTest.Basic
@@ -108,6 +125,7 @@
 -PrintBrowserTest.LazyLoadedIframeFetchedCrossOrigin
 -PrintPreviewDialogControllerBrowserTest.ReloadInitiatorTab
 -PrintPreviewDialogControllerBrowserTest.TaskManagementTest
+-ProcessesApiTest.CannotTerminateBrowserProcess
 -ProfileBrowserTest.CreateOldProfileAsynchronous
 -ProfileBrowserTestWithoutDestroyProfile.DISABLE_DestroyRegularProfileBeforeOTRs
 -ProfileHelperTest.DeleteSoleProfile
@@ -115,6 +133,10 @@
 -ReaderModeIconViewBrowserTest.NonSecurePagesNotDistillable
 -RealboxSearchPreloadBrowserTest.SearchPreloadSuccess
 -RegionCaptureBrowserCropTestInstantiation/RegionCaptureBrowserCropTest.CanCropTo/0
+-RegionCaptureBrowserCropTestInstantiation/RegionCaptureBrowserCropTest.CanCropTo/1
+-RegionCaptureBrowserCropTestInstantiation/RegionCaptureBrowserCropTest.CanCropTo/2
+-RegionCaptureBrowserCropTestInstantiation/RegionCaptureBrowserCropTest.CanCropTo/3
+-RegionCaptureBrowserCropTestInstantiation/RegionCaptureBrowserCropTest.CanCropTo/4
 -RegionCaptureBrowserCropTestInstantiation/RegionCaptureBrowserCropTest.CanCropTo/5
 -RegionCaptureBrowserCropTestInstantiation/RegionCaptureBrowserCropTest.CanCropTo/6
 -RegionCaptureBrowserCropTestInstantiation/RegionCaptureBrowserCropTest.CanCropTo/7
@@ -130,6 +152,7 @@
 -RegionCaptureBrowserCropTestInstantiation/RegionCaptureBrowserCropTest.CanCropTo/17
 -RegionCaptureBrowserTest.CropToAllowedIfEmbeddedFrameCropsToElementInEmbedded
 -RegionCaptureBrowserTest.CropToAllowedIfTopLevelCropsToElementInTopLevel
+-RegionCaptureBrowserTest.CropToAllowedToUncrop
 -RegionCaptureClonesBrowserTest.CanCloneCroppedTracks
 -RegionCaptureClonesBrowserTest.CannotRecropClone
 -RegionCaptureClonesBrowserTest.CannotRecropTrackThatHasClone
@@ -160,4 +183,9 @@
 -WebViewTests/WebViewTest.SpatialNavigationJavascriptAPI/SiteIsolationForGuestsDisabled
 -WorkerDevToolsTest.PauseInSharedWorkerInitialization
 -VariationsSafeModeEndToEndBrowserTest.ExtendedSafeModeEndToEnd
+-_/RegionCaptureMultiCaptureBrowserTest.CannotSelfCaptureAgainIfCropped/1
+-_/RegionCaptureMultiCaptureBrowserTest.CannotSelfCaptureAgainIfCropped/0
+-_/RegionCaptureMultiCaptureBrowserTest.CannotSelfCaptureAgainIfCroppedAndUncropped/0
+-_/RegionCaptureMultiCaptureBrowserTest.CannotSelfCaptureAgainIfCroppedAndUncropped/1
+-_/RegionCaptureMultiCaptureBrowserTest.CanSelfCaptureAgainIfCroppedSessionStopped/1
 -_/RegionCaptureSelfCaptureOnlyBrowserTest.CropTo/EmbeddedFrameSelfCapturingAndCroppingToElementInOwnTabsEmbeddedFrame
diff --git a/third_party/blink/common/privacy_budget/BUILD.gn b/third_party/blink/common/privacy_budget/BUILD.gn
index 224b271..41b9537 100644
--- a/third_party/blink/common/privacy_budget/BUILD.gn
+++ b/third_party/blink/common/privacy_budget/BUILD.gn
@@ -23,6 +23,7 @@
     "identifiability_sample_collector_test_utils.h",
     "identifiability_study_document_created.cc",
     "identifiability_study_settings.cc",
+    "identifiability_study_worker_client_added.cc",
     "identifiable_token_builder.cc",
   ]
 
diff --git a/third_party/blink/common/privacy_budget/identifiability_metric_builder.cc b/third_party/blink/common/privacy_budget/identifiability_metric_builder.cc
index 199781c..3407dec 100644
--- a/third_party/blink/common/privacy_budget/identifiability_metric_builder.cc
+++ b/third_party/blink/common/privacy_budget/identifiability_metric_builder.cc
@@ -4,7 +4,7 @@
 
 #include <iterator>
 
-#include "base/trace_event/trace_event.h"
+#include "base/trace_event/typed_macros.h"
 #include "services/metrics/public/cpp/ukm_source_id.h"
 #include "services/metrics/public/mojom/ukm_interface.mojom.h"
 #include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h"
@@ -21,11 +21,9 @@
 IdentifiabilityMetricBuilder& IdentifiabilityMetricBuilder::Add(
     IdentifiableSurface surface,
     IdentifiableToken value) {
-  // Note: tracing will only work if identifiability study is enabled first
-  TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("identifiability"),
-               "IdentifiableSurface", "key",
-               base::NumberToString(surface.ToUkmMetricHash()));
-
+  TRACE_EVENT_INSTANT(TRACE_DISABLED_BY_DEFAULT("identifiability"),
+                      "CallIdentifiableSurface", "key",
+                      surface.ToUkmMetricHash());
   metrics_.emplace_back(surface, value);
   return *this;
 }
diff --git a/third_party/blink/common/privacy_budget/identifiability_study_settings.cc b/third_party/blink/common/privacy_budget/identifiability_study_settings.cc
index 773edab..33515f3 100644
--- a/third_party/blink/common/privacy_budget/identifiability_study_settings.cc
+++ b/third_party/blink/common/privacy_budget/identifiability_study_settings.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h"
 
+#include <initializer_list>
 #include <random>
 
 #include "base/check.h"
@@ -11,13 +12,23 @@
 #include "base/no_destructor.h"
 #include "base/synchronization/atomic_flag.h"
 #include "base/threading/sequence_local_storage_slot.h"
+#include "base/trace_event/common/trace_event_common.h"
+#include "base/trace_event/trace_event.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/privacy_budget/identifiability_study_settings_provider.h"
+#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h"
 
 namespace blink {
 
 namespace {
 
+bool IdentifiabilityTracingEnabled() {
+  bool tracing_enabled;
+  TRACE_EVENT_CATEGORY_GROUP_ENABLED(
+      TRACE_DISABLED_BY_DEFAULT("identifiability"), &tracing_enabled);
+  return tracing_enabled;
+}
+
 // IdentifiabilityStudySettings is meant to be used as a global singleton. Its
 // use is subject to the following constraints.
 //
@@ -125,7 +136,7 @@
 
 bool IdentifiabilityStudySettings::ShouldSampleSurface(
     IdentifiableSurface surface) const {
-  if (LIKELY(!is_enabled_))
+  if (LIKELY(!ShouldSampleAnything()))
     return false;
 
   if (LIKELY(!is_any_surface_or_type_blocked_))
@@ -136,7 +147,7 @@
 
 bool IdentifiabilityStudySettings::ShouldSampleType(
     IdentifiableSurface::Type type) const {
-  if (LIKELY(!is_enabled_))
+  if (LIKELY(!ShouldSampleAnything()))
     return false;
 
   if (LIKELY(!is_any_surface_or_type_blocked_))
@@ -145,8 +156,28 @@
   return provider_->IsTypeAllowed(type);
 }
 
+bool IdentifiabilityStudySettings::ShouldSampleAnyType(
+    std::initializer_list<IdentifiableSurface::Type> types) const {
+  if (LIKELY(!ShouldSampleAnything()))
+    return false;
+
+  if (LIKELY(!is_any_surface_or_type_blocked_))
+    return true;
+
+  for (IdentifiableSurface::Type type : types) {
+    if (provider_->IsTypeAllowed(type))
+      return true;
+  }
+
+  return false;
+}
+
+bool IdentifiabilityStudySettings::ShouldSampleAnything() const {
+  return IsActive() || IdentifiabilityTracingEnabled();
+}
+
 bool IdentifiabilityStudySettings::ShouldActivelySample() const {
-  if (LIKELY(!is_enabled_))
+  if (LIKELY(!IsActive()))
     return false;
   return provider_->ShouldActivelySample();
 }
diff --git a/third_party/blink/common/privacy_budget/identifiability_study_worker_client_added.cc b/third_party/blink/common/privacy_budget/identifiability_study_worker_client_added.cc
new file mode 100644
index 0000000..af00fd4
--- /dev/null
+++ b/third_party/blink/common/privacy_budget/identifiability_study_worker_client_added.cc
@@ -0,0 +1,58 @@
+// 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.
+
+#include "third_party/blink/public/common/privacy_budget/identifiability_study_worker_client_added.h"
+
+#include "services/metrics/public/cpp/metrics_export.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
+#include "services/metrics/public/cpp/ukm_source_id.h"
+#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h"
+
+namespace blink {
+
+IdentifiabilityStudyWorkerClientAdded::IdentifiabilityStudyWorkerClientAdded(
+    ukm::SourceId source_id)
+    : source_id_(source_id) {}
+
+IdentifiabilityStudyWorkerClientAdded::
+    ~IdentifiabilityStudyWorkerClientAdded() = default;
+
+IdentifiabilityStudyWorkerClientAdded&
+IdentifiabilityStudyWorkerClientAdded::SetClientSourceId(
+    ukm::SourceId client_source_id) {
+  client_source_id_ = client_source_id;
+  return *this;
+}
+
+IdentifiabilityStudyWorkerClientAdded&
+IdentifiabilityStudyWorkerClientAdded::SetWorkerType(
+    blink::IdentifiableSurface::WorkerType worker_type) {
+  worker_type_ = worker_type;
+  return *this;
+}
+
+void IdentifiabilityStudyWorkerClientAdded::Record(ukm::UkmRecorder* recorder) {
+  using Metrics = blink::IdentifiableSurface::ReservedSurfaceMetrics;
+  base::flat_map<uint64_t, int64_t> metrics = {
+      {
+          IdentifiableSurface::FromTypeAndToken(
+              blink::IdentifiableSurface::Type::kReservedInternal,
+              Metrics::kWorkerClientAdded_ClientSourceId)
+              .ToUkmMetricHash(),
+          client_source_id_,
+      },
+      {
+          IdentifiableSurface::FromTypeAndToken(
+              blink::IdentifiableSurface::Type::kReservedInternal,
+              Metrics::kWorkerClientAdded_WorkerType)
+              .ToUkmMetricHash(),
+          static_cast<int64_t>(worker_type_),
+      },
+  };
+
+  recorder->AddEntry(ukm::mojom::UkmEntry::New(
+      source_id_, ukm::builders::Identifiability::kEntryNameHash, metrics));
+}
+
+}  // namespace blink
diff --git a/third_party/blink/public/common/privacy_budget/BUILD.gn b/third_party/blink/public/common/privacy_budget/BUILD.gn
index 6c5b04a4..1fad127 100644
--- a/third_party/blink/public/common/privacy_budget/BUILD.gn
+++ b/third_party/blink/public/common/privacy_budget/BUILD.gn
@@ -22,6 +22,7 @@
     "identifiability_study_document_created.h",
     "identifiability_study_settings.h",
     "identifiability_study_settings_provider.h",
+    "identifiability_study_worker_client_added.h",
     "identifiable_sample.h",
     "identifiable_surface.h",
     "identifiable_token.h",
diff --git a/third_party/blink/public/common/privacy_budget/identifiability_study_settings.h b/third_party/blink/public/common/privacy_budget/identifiability_study_settings.h
index 7d6beb644..904b6c15 100644
--- a/third_party/blink/public/common/privacy_budget/identifiability_study_settings.h
+++ b/third_party/blink/public/common/privacy_budget/identifiability_study_settings.h
@@ -61,22 +61,21 @@
 
   // Returns true if the study is active for this client. Once if it returns
   // true, it doesn't return false at any point after. The converse is not true.
+  // Note that metrics might still need to be sampled (because of tracing) even
+  // if this returns `false`. Use one of the `ShouldSample...` methods below for
+  // deciding whether a surface needs to be sampled.
   bool IsActive() const;
 
   // Returns true if |surface| should be sampled.
-  //
-  // Will always return false if IsActive() is false. If the study is inactive,
-  // all surfaces are considered to be blocked. Hence it is sufficient to call
-  // this function directly instead of calling IsActive() before it.
   bool ShouldSampleSurface(IdentifiableSurface surface) const;
 
   // Returns true if |type| should be sampled.
-  //
-  // Will always return false if IsActive() is false. If the study is inactive,
-  // all surface types are considered to be blocked. Hence it is sufficient to
-  // call this function directly instead of calling IsActive() before it.
   bool ShouldSampleType(IdentifiableSurface::Type type) const;
 
+  // Returns true if any of |types| should be sampled.
+  bool ShouldSampleAnyType(
+      std::initializer_list<IdentifiableSurface::Type> types) const;
+
   // Convenience method for determining whether the surface constructable from
   // the type (|kWebFeature|) and the |feature| is allowed. See
   // ShouldSampleSurface for more detail.
@@ -98,6 +97,9 @@
       delete;
 
  private:
+  // If this returns `false`, then nothing should be sampled.
+  bool ShouldSampleAnything() const;
+
   const std::unique_ptr<IdentifiabilityStudySettingsProvider> provider_;
   const bool is_enabled_ = false;
   const bool is_any_surface_or_type_blocked_ = false;
diff --git a/third_party/blink/public/common/privacy_budget/identifiability_study_worker_client_added.h b/third_party/blink/public/common/privacy_budget/identifiability_study_worker_client_added.h
new file mode 100644
index 0000000..0348b6e
--- /dev/null
+++ b/third_party/blink/public/common/privacy_budget/identifiability_study_worker_client_added.h
@@ -0,0 +1,39 @@
+// 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.
+
+#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_PRIVACY_BUDGET_IDENTIFIABILITY_STUDY_WORKER_CLIENT_ADDED_H_
+#define THIRD_PARTY_BLINK_PUBLIC_COMMON_PRIVACY_BUDGET_IDENTIFIABILITY_STUDY_WORKER_CLIENT_ADDED_H_
+
+#include "services/metrics/public/cpp/ukm_recorder.h"
+#include "services/metrics/public/cpp/ukm_source_id.h"
+#include "third_party/blink/public/common/common_export.h"
+#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h"
+
+namespace blink {
+
+class BLINK_COMMON_EXPORT IdentifiabilityStudyWorkerClientAdded {
+ public:
+  // Constructs an IdentifiabilityStudyWorkerClientAdded for the given SourceId.
+  explicit IdentifiabilityStudyWorkerClientAdded(ukm::SourceId source_id);
+
+  ~IdentifiabilityStudyWorkerClientAdded();
+
+  // Record collected metrics to `recorder`.
+  void Record(ukm::UkmRecorder* recorder);
+
+  IdentifiabilityStudyWorkerClientAdded& SetClientSourceId(
+      ukm::SourceId client_source_id);
+
+  IdentifiabilityStudyWorkerClientAdded& SetWorkerType(
+      blink::IdentifiableSurface::WorkerType worker_type);
+
+ private:
+  const ukm::SourceId source_id_;
+  ukm::SourceId client_source_id_;
+  blink::IdentifiableSurface::WorkerType worker_type_;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_PUBLIC_COMMON_PRIVACY_BUDGET_IDENTIFIABILITY_STUDY_WORKER_CLIENT_ADDED_H_
diff --git a/third_party/blink/public/common/privacy_budget/identifiable_surface.h b/third_party/blink/public/common/privacy_budget/identifiable_surface.h
index 53e48d1..4086266 100644
--- a/third_party/blink/public/common/privacy_budget/identifiable_surface.h
+++ b/third_party/blink/public/common/privacy_budget/identifiable_surface.h
@@ -271,8 +271,17 @@
     kDocumentCreated_IsCrossSiteFrame = 1,
     kDocumentCreated_IsMainFrame = 2,
     kDocumentCreated_NavigationSourceId = 3,
-    kMax = kDocumentCreated_NavigationSourceId
+    kWorkerClientAdded_ClientSourceId = 4,
+    kWorkerClientAdded_WorkerType = 5,
+    kMax = kWorkerClientAdded_WorkerType
   };
+
+  enum class WorkerType {
+    kSharedWorker = 0,
+    kServiceWorker = 1,
+    kMax = kServiceWorker,
+  };
+
   static_assert(
       static_cast<uint64_t>(ReservedSurfaceMetrics::kMax) <
           std::min(
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
index 9321481..dff1b3d 100644
--- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl
+++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -7682,6 +7682,14 @@
       # Recommendation for manifest's id attribute to match current id computed from start_url
       optional string recommendedId
 
+  experimental command getAdScriptId
+    parameters
+      FrameId frameId
+    returns
+      # Identifies the bottom-most script which caused the frame to be labelled
+      # as an ad. Only sent if frame is labelled as an ad and id is available.
+      optional AdScriptId adScriptId
+
   # Returns all browser cookies for the page and all of its subframes. Depending
   # on the backend support, will return detailed cookie information in the
   # `cookies` field.
@@ -8129,7 +8137,8 @@
       optional Runtime.StackTrace stack
       # Identifies the bottom-most script which caused the frame to be labelled
       # as an ad. Only sent if frame is labelled as an ad and id is available.
-      experimental optional AdScriptId adScriptId
+      # Deprecated: use Page.getAdScriptId instead.
+      experimental deprecated optional AdScriptId adScriptId
 
   # Fired when frame no longer has a scheduled navigation.
   deprecated event frameClearedScheduledNavigation
@@ -9945,7 +9954,9 @@
       optional string method
       # If set, overrides the post data in the request.
       optional binary postData
-      # If set, overrides the request headers.
+      # If set, overrides the request headers. Note that the overrides do not
+      # extend to subsequent redirect hops, if a redirect happens. Another override
+      # may be applied to a different request produced by a redirect.
       optional array of HeaderEntry headers
       # If set, overrides response interception behavior for this request.
       experimental optional boolean interceptResponse
diff --git a/third_party/blink/public/mojom/file_system_access/file_system_access_directory_handle.mojom b/third_party/blink/public/mojom/file_system_access/file_system_access_directory_handle.mojom
index ef7dbc3..9c5e70c4 100644
--- a/third_party/blink/public/mojom/file_system_access/file_system_access_directory_handle.mojom
+++ b/third_party/blink/public/mojom/file_system_access/file_system_access_directory_handle.mojom
@@ -66,8 +66,7 @@
   // Returns all the direct children of this directory.
   GetEntries(pending_remote<FileSystemAccessDirectoryEntriesListener> listener);
 
-  // Renames the directory represented by this handle to `new_entry_name`, which
-  // cannot be empty. This is guaranteed to be atomic.
+  // Renames the directory represented by this handle to `new_entry_name`.
   // Returns an error if the directory does not exist.
   Rename(string new_entry_name) => (FileSystemAccessError result);
 
diff --git a/third_party/blink/public/mojom/file_system_access/file_system_access_file_handle.mojom b/third_party/blink/public/mojom/file_system_access/file_system_access_file_handle.mojom
index 739cd6c..bb48f69 100644
--- a/third_party/blink/public/mojom/file_system_access/file_system_access_file_handle.mojom
+++ b/third_party/blink/public/mojom/file_system_access/file_system_access_file_handle.mojom
@@ -68,8 +68,7 @@
   CreateFileWriter(bool keep_existing_data, bool auto_close) => (
       FileSystemAccessError result, pending_remote<FileSystemAccessFileWriter>? writer);
 
-  // Renames the file represented by this handle to `new_entry_name`, which
-  // cannot be empty. This is guaranteed to be atomic.
+  // Renames the file represented by this handle to `new_entry_name`.
   // Returns an error if the file does not exist.
   Rename(string new_entry_name) => (FileSystemAccessError result);
 
diff --git a/third_party/blink/public/mojom/webauthn/OWNERS b/third_party/blink/public/mojom/webauthn/OWNERS
index dd7ddf4..08850f4 100644
--- a/third_party/blink/public/mojom/webauthn/OWNERS
+++ b/third_party/blink/public/mojom/webauthn/OWNERS
@@ -1,3 +1,2 @@
-mkwst@chromium.org
 per-file *.mojom=set noparent
 per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/third_party/blink/public/platform/media/web_media_player_builder.h b/third_party/blink/public/platform/media/web_media_player_builder.h
index bd5247ce..a59f68d4 100644
--- a/third_party/blink/public/platform/media/web_media_player_builder.h
+++ b/third_party/blink/public/platform/media/web_media_player_builder.h
@@ -22,6 +22,7 @@
 
 namespace base {
 class SingleThreadTaskRunner;
+class SequencedTaskRunner;
 class TaskRunner;
 }  // namespace base
 
@@ -78,7 +79,7 @@
       media::MediaPlayerLoggingID player_id,
       DeferLoadCB defer_load_cb,
       scoped_refptr<media::SwitchableAudioRendererSink> audio_renderer_sink,
-      scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+      scoped_refptr<base::SequencedTaskRunner> media_task_runner,
       scoped_refptr<base::TaskRunner> worker_task_runner,
       scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
       scoped_refptr<base::SingleThreadTaskRunner>
diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h
index bb829520..13ddc13 100644
--- a/third_party/blink/public/platform/platform.h
+++ b/third_party/blink/public/platform/platform.h
@@ -38,6 +38,7 @@
 
 #include "base/callback.h"
 #include "base/memory/scoped_refptr.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/threading/platform_thread.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
@@ -345,7 +346,7 @@
 
   // Returns the task runner of the media thread.
   // This method should only be called on the main thread, or it crashes.
-  virtual scoped_refptr<base::SingleThreadTaskRunner> MediaThreadTaskRunner() {
+  virtual scoped_refptr<base::SequencedTaskRunner> MediaThreadTaskRunner() {
     return nullptr;
   }
 
diff --git a/third_party/blink/public/platform/web_graphics_context_3d_provider.h b/third_party/blink/public/platform/web_graphics_context_3d_provider.h
index 9979508..d82796e 100644
--- a/third_party/blink/public/platform/web_graphics_context_3d_provider.h
+++ b/third_party/blink/public/platform/web_graphics_context_3d_provider.h
@@ -97,7 +97,7 @@
   virtual gpu::raster::RasterInterface* RasterInterface() = 0;
   virtual gpu::webgpu::WebGPUInterface* WebGPUInterface() = 0;
   virtual bool IsContextLost() = 0;  // Has the GPU driver lost this context?
-  virtual bool BindToCurrentThread() = 0;
+  virtual bool BindToCurrentSequence() = 0;
   virtual GrDirectContext* GetGrContext() = 0;
   virtual const gpu::Capabilities& GetCapabilities() const = 0;
   virtual const gpu::GpuFeatureInfo& GetGpuFeatureInfo() const = 0;
diff --git a/third_party/blink/public/web/modules/mediastream/DEPS b/third_party/blink/public/web/modules/mediastream/DEPS
index 9238d9d4..a675dac 100644
--- a/third_party/blink/public/web/modules/mediastream/DEPS
+++ b/third_party/blink/public/web/modules/mediastream/DEPS
@@ -4,6 +4,7 @@
     "+base/logging.h",
     "+base/memory/weak_ptr.h",
     "+base/task/single_thread_task_runner.h",
+    "+base/task/sequenced_task_runner.h",
     "+base/synchronization/lock.h",
     "+base/token.h",
     "+base/threading/thread_checker.h",
diff --git a/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h b/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h
index f8c640d..a71efae 100644
--- a/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h
+++ b/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h
@@ -10,6 +10,7 @@
 
 #include "base/memory/weak_ptr.h"
 #include "base/synchronization/lock.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/threading/thread_checker.h"
 #include "base/time/time.h"
@@ -82,7 +83,7 @@
       scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner,
       scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
       scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
-      scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+      scoped_refptr<base::SequencedTaskRunner> media_task_runner,
       scoped_refptr<base::TaskRunner> worker_task_runner,
       media::GpuVideoAcceleratorFactories* gpu_factories,
       const WebString& sink_id,
@@ -305,7 +306,7 @@
   const scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner_;
   const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
   const scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
-  const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+  const scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
 
   const scoped_refptr<base::TaskRunner> worker_task_runner_;
   media::GpuVideoAcceleratorFactories* gpu_factories_;
diff --git a/third_party/blink/renderer/bindings/OWNERS b/third_party/blink/renderer/bindings/OWNERS
index 218c8a90..e16826c4 100644
--- a/third_party/blink/renderer/bindings/OWNERS
+++ b/third_party/blink/renderer/bindings/OWNERS
@@ -3,7 +3,6 @@
 japhet@chromium.org
 jbroman@chromium.org
 kouhei@chromium.org
-mkwst@chromium.org
 mlippautz@chromium.org
 yukishiino@chromium.org
 
diff --git a/third_party/blink/renderer/bindings/core/v8/boxed_v8_module.h b/third_party/blink/renderer/bindings/core/v8/boxed_v8_module.h
index 486b3a2..f1aba61d 100644
--- a/third_party/blink/renderer/bindings/core/v8/boxed_v8_module.h
+++ b/third_party/blink/renderer/bindings/core/v8/boxed_v8_module.h
@@ -66,9 +66,8 @@
 namespace WTF {
 
 template <>
-struct DefaultHash<blink::Member<blink::BoxedV8Module>> {
-  using Hash = blink::BoxedV8ModuleHash;
-};
+struct DefaultHash<blink::Member<blink::BoxedV8Module>>
+    : blink::BoxedV8ModuleHash {};
 
 }  // namespace WTF
 
diff --git a/third_party/blink/renderer/bindings/core/v8/boxed_v8_module_test.cc b/third_party/blink/renderer/bindings/core/v8/boxed_v8_module_test.cc
index 52eb310..bc167228 100644
--- a/third_party/blink/renderer/bindings/core/v8/boxed_v8_module_test.cc
+++ b/third_party/blink/renderer/bindings/core/v8/boxed_v8_module_test.cc
@@ -48,9 +48,8 @@
   EXPECT_FALSE(BoxedV8ModuleHash::Equal(module_a, module_b));
 
   EXPECT_NE(
-      DefaultHash<blink::Member<blink::BoxedV8Module>>::Hash::GetHash(module_a),
-      DefaultHash<blink::Member<blink::BoxedV8Module>>::Hash::GetHash(
-          module_b));
+      DefaultHash<blink::Member<blink::BoxedV8Module>>::GetHash(module_a),
+      DefaultHash<blink::Member<blink::BoxedV8Module>>::GetHash(module_b));
 }
 
 }  // namespace
diff --git a/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.h b/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.h
index e38615a..f467d6b 100644
--- a/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.h
+++ b/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.h
@@ -58,8 +58,8 @@
   static unsigned GetHash(const v8::CpuProfileNode* node) {
     return StringHash::GetHash(node->GetFunctionNameStr()) ^
            StringHash::GetHash(node->GetScriptResourceNameStr()) ^
-           DefaultHash<unsigned>::Hash().GetHash(node->GetLineNumber()) ^
-           DefaultHash<unsigned>::Hash().GetHash(node->GetColumnNumber());
+           DefaultHash<unsigned>::GetHash(node->GetLineNumber()) ^
+           DefaultHash<unsigned>::GetHash(node->GetColumnNumber());
   }
 
   static const bool safe_to_compare_to_empty_or_deleted = false;
diff --git a/third_party/blink/renderer/core/animation/property_handle.h b/third_party/blink/renderer/core/animation/property_handle.h
index 86b9e23..3646e97 100644
--- a/third_party/blink/renderer/core/animation/property_handle.h
+++ b/third_party/blink/renderer/core/animation/property_handle.h
@@ -133,19 +133,17 @@
 
 template <>
 struct DefaultHash<blink::PropertyHandle> {
-  struct Hash {
-    STATIC_ONLY(Hash);
-    static unsigned GetHash(const blink::PropertyHandle& handle) {
-      return handle.GetHash();
-    }
+  STATIC_ONLY(DefaultHash);
+  static unsigned GetHash(const blink::PropertyHandle& handle) {
+    return handle.GetHash();
+  }
 
-    static bool Equal(const blink::PropertyHandle& a,
-                      const blink::PropertyHandle& b) {
-      return a == b;
-    }
+  static bool Equal(const blink::PropertyHandle& a,
+                    const blink::PropertyHandle& b) {
+    return a == b;
+  }
 
-    static const bool safe_to_compare_to_empty_or_deleted = true;
-  };
+  static const bool safe_to_compare_to_empty_or_deleted = true;
 };
 
 template <>
diff --git a/third_party/blink/renderer/core/css/container_selector.h b/third_party/blink/renderer/core/css/container_selector.h
index fe86c908..5d4a268e 100644
--- a/third_party/blink/renderer/core/css/container_selector.h
+++ b/third_party/blink/renderer/core/css/container_selector.h
@@ -75,20 +75,18 @@
 
 template <>
 struct DefaultHash<blink::ContainerSelector> {
-  struct Hash {
-    STATIC_ONLY(Hash);
-    static unsigned GetHash(const blink::ContainerSelector& selector) {
-      return selector.GetHash();
-    }
+  STATIC_ONLY(DefaultHash);
+  static unsigned GetHash(const blink::ContainerSelector& selector) {
+    return selector.GetHash();
+  }
 
-    static bool Equal(const blink::ContainerSelector& a,
-                      const blink::ContainerSelector& b) {
-      return a == b;
-    }
+  static bool Equal(const blink::ContainerSelector& a,
+                    const blink::ContainerSelector& b) {
+    return a == b;
+  }
 
-    static const bool safe_to_compare_to_empty_or_deleted =
-        DefaultHash<AtomicString>::Hash::safe_to_compare_to_empty_or_deleted;
-  };
+  static const bool safe_to_compare_to_empty_or_deleted =
+      DefaultHash<AtomicString>::safe_to_compare_to_empty_or_deleted;
 };
 
 template <>
diff --git a/third_party/blink/renderer/core/css/css_property_name.h b/third_party/blink/renderer/core/css/css_property_name.h
index f60191d..99abfc9 100644
--- a/third_party/blink/renderer/core/css/css_property_name.h
+++ b/third_party/blink/renderer/core/css/css_property_name.h
@@ -88,19 +88,17 @@
 
 template <>
 struct DefaultHash<blink::CSSPropertyName> {
-  struct Hash {
-    STATIC_ONLY(Hash);
-    static unsigned GetHash(const blink::CSSPropertyName& name) {
-      return name.GetHash();
-    }
+  STATIC_ONLY(DefaultHash);
+  static unsigned GetHash(const blink::CSSPropertyName& name) {
+    return name.GetHash();
+  }
 
-    static bool Equal(const blink::CSSPropertyName& a,
-                      const blink::CSSPropertyName& b) {
-      return a == b;
-    }
+  static bool Equal(const blink::CSSPropertyName& a,
+                    const blink::CSSPropertyName& b) {
+    return a == b;
+  }
 
-    static const bool safe_to_compare_to_empty_or_deleted = true;
-  };
+  static const bool safe_to_compare_to_empty_or_deleted = true;
 };
 
 template <>
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 675b8e1e..a8c1bd9 100644
--- a/third_party/blink/renderer/core/css/css_value_pool.h
+++ b/third_party/blink/renderer/core/css/css_value_pool.h
@@ -77,7 +77,7 @@
   };
   using ColorValueCache = HeapHashMap<Color,
                                       Member<CSSColor>,
-                                      typename DefaultHash<Color>::Hash,
+                                      DefaultHash<Color>,
                                       ColorHashTraitsForCSSValuePool>;
   static const unsigned kMaximumColorCacheSize = 512;
   using FontFaceValueCache =
diff --git a/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h b/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h
index e058bfa..895b61c 100644
--- a/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h
+++ b/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h
@@ -114,7 +114,7 @@
   // |RemoveCachedMatchedPropertiesWithDeadEntries|.
   using Cache = HeapHashMap<unsigned,
                             Member<CachedMatchedProperties>,
-                            DefaultHash<unsigned>::Hash,
+                            DefaultHash<unsigned>,
                             HashTraits<unsigned>>;
 
   void RemoveCachedMatchedPropertiesWithDeadEntries(const LivenessBroker&);
diff --git a/third_party/blink/renderer/core/dom/node_lists_node_data.h b/third_party/blink/renderer/core/dom/node_lists_node_data.h
index 98dd5839..79cc7234 100644
--- a/third_party/blink/renderer/core/dom/node_lists_node_data.h
+++ b/third_party/blink/renderer/core/dom/node_lists_node_data.h
@@ -62,7 +62,7 @@
   struct NodeListAtomicCacheMapEntryHash {
     STATIC_ONLY(NodeListAtomicCacheMapEntryHash);
     static unsigned GetHash(const NamedNodeListKey& entry) {
-      return DefaultHash<AtomicString>::Hash::GetHash(
+      return DefaultHash<AtomicString>::GetHash(
                  entry.second == CSSSelector::UniversalSelectorAtom()
                      ? g_star_atom
                      : entry.second) +
@@ -72,7 +72,7 @@
       return a == b;
     }
     static const bool safe_to_compare_to_empty_or_deleted =
-        DefaultHash<AtomicString>::Hash::safe_to_compare_to_empty_or_deleted;
+        DefaultHash<AtomicString>::safe_to_compare_to_empty_or_deleted;
   };
 
   typedef HeapHashMap<NamedNodeListKey,
diff --git a/third_party/blink/renderer/core/dom/qualified_name.h b/third_party/blink/renderer/core/dom/qualified_name.h
index a3fc7fab..ec8851b 100644
--- a/third_party/blink/renderer/core/dom/qualified_name.h
+++ b/third_party/blink/renderer/core/dom/qualified_name.h
@@ -229,9 +229,7 @@
 namespace WTF {
 
 template <>
-struct DefaultHash<blink::QualifiedName> {
-  typedef blink::QualifiedNameHash Hash;
-};
+struct DefaultHash<blink::QualifiedName> : blink::QualifiedNameHash {};
 
 template <>
 struct HashTraits<blink::QualifiedName>
diff --git a/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc b/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc
index ad4d036c7..7596608 100644
--- a/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc
+++ b/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc
@@ -142,11 +142,18 @@
     return nullptr;
   }
   ukm::SourceId GetUkmSourceId() override { return ukm::kInvalidSourceId; }
-  void OnStartedUsingFeature(SchedulingPolicy::Feature feature,
-                             const SchedulingPolicy& policy) override {}
-  void OnStoppedUsingFeature(SchedulingPolicy::Feature feature,
-                             const SchedulingPolicy& policy) override {}
-  base::WeakPtr<FrameOrWorkerScheduler> GetSchedulingAffectingFeatureWeakPtr()
+  void OnStartedUsingNonStickyFeature(
+      SchedulingPolicy::Feature feature,
+      const SchedulingPolicy& policy,
+      std::unique_ptr<SourceLocation> source_location,
+      SchedulingAffectingFeatureHandle* handle) override {}
+  void OnStartedUsingStickyFeature(
+      SchedulingPolicy::Feature feature,
+      const SchedulingPolicy& policy,
+      std::unique_ptr<SourceLocation> source_location) override {}
+  void OnStoppedUsingNonStickyFeature(
+      SchedulingAffectingFeatureHandle* handle) override {}
+  base::WeakPtr<FrameOrWorkerScheduler> GetFrameOrWorkerSchedulerWeakPtr()
       override {
     return weak_ptr_factory_.GetWeakPtr();
   }
diff --git a/third_party/blink/renderer/core/frame/csp/OWNERS b/third_party/blink/renderer/core/frame/csp/OWNERS
index af159751..1245fcd 100644
--- a/third_party/blink/renderer/core/frame/csp/OWNERS
+++ b/third_party/blink/renderer/core/frame/csp/OWNERS
@@ -1,3 +1,2 @@
 antoniosartori@chromium.org
 arthursonzogni@chromium.org
-mkwst@chromium.org
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index 79bb5259..7d3a706 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -2297,7 +2297,13 @@
 }
 
 void LocalFrame::UpdateBackForwardCacheDisablingFeatures(
-    uint64_t features_mask) {
+    uint64_t features_mask,
+    const BFCacheBlockingFeatureAndLocations&
+        non_sticky_features_and_js_locations,
+    const BFCacheBlockingFeatureAndLocations&
+        sticky_features_and_js_locations) {
+  // TODO(crbug.com/1366675): Add two Vectors to argument of
+  // DidChangeBackForwardCacheDisablingFeatures
   GetBackForwardCacheControllerHostRemote()
       .DidChangeBackForwardCacheDisablingFeatures(features_mask);
 }
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h
index 4296d02..772ce6f 100644
--- a/third_party/blink/renderer/core/frame/local_frame.h
+++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -845,7 +845,12 @@
   ukm::UkmRecorder* GetUkmRecorder() override;
   ukm::SourceId GetUkmSourceId() override;
   void UpdateTaskTime(base::TimeDelta time) override;
-  void UpdateBackForwardCacheDisablingFeatures(uint64_t features_mask) override;
+  void UpdateBackForwardCacheDisablingFeatures(
+      uint64_t features_mask,
+      const BFCacheBlockingFeatureAndLocations&
+          non_sticky_features_and_js_locations,
+      const BFCacheBlockingFeatureAndLocations&
+          sticky_features_and_js_locations) override;
   const base::UnguessableToken& GetAgentClusterId() const override;
 
   // Activates the user activation states of this frame and all its ancestors.
diff --git a/third_party/blink/renderer/core/frame/location_report_body.cc b/third_party/blink/renderer/core/frame/location_report_body.cc
index 1373359..142e45c 100644
--- a/third_party/blink/renderer/core/frame/location_report_body.cc
+++ b/third_party/blink/renderer/core/frame/location_report_body.cc
@@ -44,10 +44,9 @@
   const absl::optional<uint32_t> line = lineNumber(), column = columnNumber();
 
   unsigned hash = sourceFile().IsNull() ? 0 : sourceFile().Impl()->GetHash();
-  hash = WTF::HashInts(hash,
-                       line ? DefaultHash<uint32_t>::Hash::GetHash(*line) : 0);
-  hash = WTF::HashInts(
-      hash, column ? DefaultHash<uint32_t>::Hash::GetHash(*column) : 0);
+  hash = WTF::HashInts(hash, line ? DefaultHash<uint32_t>::GetHash(*line) : 0);
+  hash =
+      WTF::HashInts(hash, column ? DefaultHash<uint32_t>::GetHash(*column) : 0);
   return hash;
 }
 
diff --git a/third_party/blink/renderer/core/frame/performance_monitor.h b/third_party/blink/renderer/core/frame/performance_monitor.h
index a2efbf06d..5ff78d11 100644
--- a/third_party/blink/renderer/core/frame/performance_monitor.h
+++ b/third_party/blink/renderer/core/frame/performance_monitor.h
@@ -164,7 +164,7 @@
   using ClientThresholds = HeapHashMap<WeakMember<Client>, base::TimeDelta>;
   HeapHashMap<Violation,
               Member<ClientThresholds>,
-              typename DefaultHash<size_t>::Hash,
+              DefaultHash<size_t>,
               WTF::UnsignedWithZeroKeyHashTraits<size_t>>
       subscriptions_;
 };
diff --git a/third_party/blink/renderer/core/highlight/highlight_registry_map_entry.h b/third_party/blink/renderer/core/highlight/highlight_registry_map_entry.h
index fa0d5af1..0fc4ad70 100644
--- a/third_party/blink/renderer/core/highlight/highlight_registry_map_entry.h
+++ b/third_party/blink/renderer/core/highlight/highlight_registry_map_entry.h
@@ -33,27 +33,25 @@
 
 template <>
 struct DefaultHash<blink::Member<blink::HighlightRegistryMapEntry>> {
-  struct Hash {
-    STATIC_ONLY(Hash);
+  STATIC_ONLY(DefaultHash);
 
-    // Note that GetHash and Equal only take into account the |highlight_name|
-    // because |HighlightRegistryMapEntry| is used for storing map entries
-    // inside a set (i.e. there can only be one map entry in the set with the
-    // same key which is |highlight_name|).
-    static inline unsigned GetHash(
-        const blink::Member<blink::HighlightRegistryMapEntry>& key) {
-      DCHECK(key);
-      return AtomicStringHash::GetHash(key->highlight_name);
-    }
-    static inline bool Equal(
-        const blink::Member<blink::HighlightRegistryMapEntry>& a,
-        const blink::Member<blink::HighlightRegistryMapEntry>& b) {
-      DCHECK(a && b);
-      return AtomicStringHash::Equal(a->highlight_name, b->highlight_name);
-    }
+  // Note that GetHash and Equal only take into account the |highlight_name|
+  // because |HighlightRegistryMapEntry| is used for storing map entries
+  // inside a set (i.e. there can only be one map entry in the set with the
+  // same key which is |highlight_name|).
+  static inline unsigned GetHash(
+      const blink::Member<blink::HighlightRegistryMapEntry>& key) {
+    DCHECK(key);
+    return AtomicStringHash::GetHash(key->highlight_name);
+  }
+  static inline bool Equal(
+      const blink::Member<blink::HighlightRegistryMapEntry>& a,
+      const blink::Member<blink::HighlightRegistryMapEntry>& b) {
+    DCHECK(a && b);
+    return AtomicStringHash::Equal(a->highlight_name, b->highlight_name);
+  }
 
-    static const bool safe_to_compare_to_empty_or_deleted = false;
-  };
+  static const bool safe_to_compare_to_empty_or_deleted = false;
 };
 
 }  // namespace WTF
diff --git a/third_party/blink/renderer/core/html/custom/custom_element_descriptor_hash.h b/third_party/blink/renderer/core/html/custom/custom_element_descriptor_hash.h
index 4ec849f..f807472 100644
--- a/third_party/blink/renderer/core/html/custom/custom_element_descriptor_hash.h
+++ b/third_party/blink/renderer/core/html/custom/custom_element_descriptor_hash.h
@@ -49,9 +49,8 @@
 };
 
 template <>
-struct DefaultHash<blink::CustomElementDescriptor> {
-  using Hash = blink::CustomElementDescriptorHash;
-};
+struct DefaultHash<blink::CustomElementDescriptor>
+    : blink::CustomElementDescriptorHash {};
 
 }  // namespace WTF
 
diff --git a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
index 57b920cd..45f6a0e 100644
--- a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
@@ -555,6 +555,7 @@
       resource_content_loader_client_id_);
   requested_compilation_cache_.clear();
   compilation_cache_.clear();
+  ad_script_identifiers_.clear();
   stopScreencast();
 
   return Response::Success();
@@ -747,6 +748,23 @@
           WrapPersistent(this), frame_id, url, std::move(callback)));
 }
 
+protocol::Response InspectorPageAgent::getAdScriptId(
+    const String& frame_id,
+    Maybe<protocol::Page::AdScriptId>* ad_script_id) {
+  if (ad_script_identifiers_.Contains(frame_id)) {
+    AdScriptIdentifier* ad_script_identifier =
+        ad_script_identifiers_.at(frame_id);
+    *ad_script_id =
+        protocol::Page::AdScriptId::create()
+            .setScriptId(String::Number(ad_script_identifier->id))
+            .setDebuggerId(ToCoreString(
+                ad_script_identifier->context_id.toString()->string()))
+            .build();
+  }
+
+  return Response::Success();
+}
+
 void InspectorPageAgent::SearchContentAfterResourcesContentLoaded(
     const String& frame_id,
     const String& url,
@@ -1046,6 +1064,9 @@
             .setDebuggerId(ToCoreString(
                 ad_script_on_stack.value().context_id.toString()->string()))
             .build();
+    ad_script_identifiers_.Set(
+        IdentifiersFactory::FrameId(frame),
+        std::make_unique<AdScriptIdentifier>(ad_script_on_stack.value()));
   }
   GetFrontend()->frameAttached(
       IdentifiersFactory::FrameId(frame),
@@ -1060,6 +1081,10 @@
 
 void InspectorPageAgent::FrameDetachedFromParent(LocalFrame* frame,
                                                  FrameDetachType type) {
+  // If the frame is swapped, we still maintain the ad script id for it.
+  if (type == FrameDetachType::kRemove)
+    ad_script_identifiers_.erase(IdentifiersFactory::FrameId(frame));
+
   GetFrontend()->frameDetached(IdentifiersFactory::FrameId(frame),
                                FrameDetachTypeToProtocol(type));
 }
diff --git a/third_party/blink/renderer/core/inspector/inspector_page_agent.h b/third_party/blink/renderer/core/inspector/inspector_page_agent.h
index 32314a2..3650a78 100644
--- a/third_party/blink/renderer/core/inspector/inspector_page_agent.h
+++ b/third_party/blink/renderer/core/inspector/inspector_page_agent.h
@@ -138,6 +138,9 @@
   void getResourceContent(const String& frame_id,
                           const String& url,
                           std::unique_ptr<GetResourceContentCallback>) override;
+  protocol::Response getAdScriptId(
+      const String& frame_id,
+      Maybe<protocol::Page::AdScriptId>* ad_script_id) override;
   void searchInResource(const String& frame_id,
                         const String& url,
                         const String& query,
@@ -296,6 +299,8 @@
       pending_isolated_worlds_;
   using FrameIsolatedWorlds = HashMap<String, scoped_refptr<DOMWrapperWorld>>;
   HeapHashMap<WeakMember<LocalFrame>, FrameIsolatedWorlds> isolated_worlds_;
+  HashMap<String, std::unique_ptr<blink::AdScriptIdentifier>>
+      ad_script_identifiers_;
   v8_inspector::V8InspectorSession* v8_session_;
   Client* client_;
   String pending_script_to_evaluate_on_load_once_;
diff --git a/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc b/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc
index efca9c8..0c5ab3f 100644
--- a/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc
+++ b/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc
@@ -61,9 +61,9 @@
 struct LegacyDOMSnapshotAgent::VectorStringHashTraits
     : public WTF::GenericHashTraits<Vector<String>> {
   static unsigned GetHash(const Vector<String>& vec) {
-    unsigned h = DefaultHash<size_t>::Hash::GetHash(vec.size());
-    for (wtf_size_t i = 0; i < vec.size(); i++) {
-      h = WTF::HashInts(h, DefaultHash<String>::Hash::GetHash(vec[i]));
+    unsigned h = DefaultHash<size_t>::GetHash(vec.size());
+    for (const String& s : vec) {
+      h = WTF::HashInts(h, DefaultHash<String>::GetHash(s));
     }
     return h;
   }
diff --git a/third_party/blink/renderer/core/layout/api/line_layout_item.h b/third_party/blink/renderer/core/layout/api/line_layout_item.h
index fbf9f2f..f80026c 100644
--- a/third_party/blink/renderer/core/layout/api/line_layout_item.h
+++ b/third_party/blink/renderer/core/layout/api/line_layout_item.h
@@ -328,15 +328,12 @@
 namespace WTF {
 
 template <>
-struct DefaultHash<blink::LineLayoutItem> {
-  using Hash = blink::LineLayoutItem::LineLayoutItemHash;
-};
+struct DefaultHash<blink::LineLayoutItem>
+    : blink::LineLayoutItem::LineLayoutItemHash {};
 
 template <>
 struct HashTraits<blink::LineLayoutItem>
-    : SimpleClassHashTraits<blink::LineLayoutItem> {
-  STATIC_ONLY(HashTraits);
-};
+    : SimpleClassHashTraits<blink::LineLayoutItem> {};
 
 }  // namespace WTF
 
diff --git a/third_party/blink/renderer/core/layout/floating_objects.h b/third_party/blink/renderer/core/layout/floating_objects.h
index f54a3dab..9d5d279 100644
--- a/third_party/blink/renderer/core/layout/floating_objects.h
+++ b/third_party/blink/renderer/core/layout/floating_objects.h
@@ -182,7 +182,7 @@
 struct FloatingObjectHashFunctions {
   STATIC_ONLY(FloatingObjectHashFunctions);
   static unsigned GetHash(FloatingObject* key) {
-    return DefaultHash<LayoutBox*>::Hash::GetHash(key->GetLayoutObject());
+    return DefaultHash<LayoutBox*>::GetHash(key->GetLayoutObject());
   }
   static unsigned GetHash(const Member<FloatingObject>& key) {
     return GetHash(key.Get());
@@ -200,7 +200,7 @@
 struct FloatingObjectHashTranslator {
   STATIC_ONLY(FloatingObjectHashTranslator);
   static unsigned GetHash(LayoutBox* key) {
-    return DefaultHash<LayoutBox*>::Hash::GetHash(key);
+    return DefaultHash<LayoutBox*>::GetHash(key);
   }
   static bool Equal(FloatingObject* a, LayoutBox* b) {
     return a->GetLayoutObject() == b;
diff --git a/third_party/blink/renderer/core/layout/grid_baseline_alignment.h b/third_party/blink/renderer/core/layout/grid_baseline_alignment.h
index 94c88bae..0f60d2b 100644
--- a/third_party/blink/renderer/core/layout/grid_baseline_alignment.h
+++ b/third_party/blink/renderer/core/layout/grid_baseline_alignment.h
@@ -193,7 +193,7 @@
 
   typedef HeapHashMap<unsigned,
                       Member<BaselineContext>,
-                      DefaultHash<unsigned>::Hash,
+                      DefaultHash<unsigned>,
                       WTF::UnsignedWithZeroKeyHashTraits<unsigned>>
       BaselineContextsMap;
 
diff --git a/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.h b/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.h
index caf6bc30..9df5cdb 100644
--- a/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.h
+++ b/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.h
@@ -196,7 +196,7 @@
 
   // Helper methods for step 4. Strech flexible tracks.
   typedef HashSet<size_t,
-                  DefaultHash<size_t>::Hash,
+                  DefaultHash<size_t>,
                   WTF::UnsignedWithZeroKeyHashTraits<size_t>>
       TrackIndexSet;
   double ComputeFlexFactorUnitSize(
diff --git a/third_party/blink/renderer/core/layout/layout_grid.cc b/third_party/blink/renderer/core/layout/layout_grid.cc
index 7dd3e8a..37e5516 100644
--- a/third_party/blink/renderer/core/layout/layout_grid.cc
+++ b/third_party/blink/renderer/core/layout/layout_grid.cc
@@ -1124,7 +1124,7 @@
   // auto-placed item's position inserted on that track. This is needed to
   // implement "sparse" packing for items locked to a given track.
   // See https://drafts.csswg.org/css-grid/#auto-placement-algo
-  HashMap<unsigned, unsigned, DefaultHash<unsigned>::Hash,
+  HashMap<unsigned, unsigned, DefaultHash<unsigned>,
           WTF::UnsignedWithZeroKeyHashTraits<unsigned>>
       minor_axis_cursors;
 
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_placement.cc b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_placement.cc
index 4f14872..3b96e183 100644
--- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_placement.cc
+++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_placement.cc
@@ -244,7 +244,7 @@
   // line inserted on that track. This is needed to implement "sparse" packing
   // for grid items locked to a given major axis track.
   // See https://drafts.csswg.org/css-grid/#auto-placement-algo.
-  HashMap<wtf_size_t, wtf_size_t, DefaultHash<wtf_size_t>::Hash,
+  HashMap<wtf_size_t, wtf_size_t, DefaultHash<wtf_size_t>,
           WTF::UnsignedWithZeroKeyHashTraits<wtf_size_t>>
       minor_cursors;
 
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc
index dd283ff4..f3dc247b 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc
@@ -254,12 +254,13 @@
 }
 
 NGInlineBoxState* NGInlineLayoutStateStack::OnOpenTag(
+    const NGConstraintSpace& space,
     const NGInlineItem& item,
     const NGInlineItemResult& item_result,
     FontBaseline baseline_type,
     NGLogicalLineItems* line_box) {
   NGInlineBoxState* box =
-      OnOpenTag(item, item_result, baseline_type, *line_box);
+      OnOpenTag(space, item, item_result, baseline_type, *line_box);
   box->needs_box_fragment = item.ShouldCreateBoxFragment();
   if (box->needs_box_fragment)
     AddBoxFragmentPlaceholder(box, line_box, baseline_type);
@@ -267,6 +268,7 @@
 }
 
 NGInlineBoxState* NGInlineLayoutStateStack::OnOpenTag(
+    const NGConstraintSpace& space,
     const NGInlineItem& item,
     const NGInlineItemResult& item_result,
     FontBaseline baseline_type,
@@ -283,6 +285,13 @@
   box->margin_inline_end = item_result.margins.inline_end;
   box->borders = item_result.borders;
   box->padding = item_result.padding;
+  if (space.IsInsideRepeatableContent()) {
+    // Avoid culled inlines when inside repeatable content (fixed-positioned
+    // elements when printing and fragmented tables with headers and footers).
+    // We cannot represent them correctly as culled.
+    if (auto* layout_inline = DynamicTo<LayoutInline>(item.GetLayoutObject()))
+      layout_inline->SetShouldCreateBoxFragment();
+  }
   return box;
 }
 
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h
index 5c61d73..aec9984a 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h
@@ -155,12 +155,14 @@
                                       NGLogicalLineItems* line_box);
 
   // Push a box state stack.
-  NGInlineBoxState* OnOpenTag(const NGInlineItem&,
+  NGInlineBoxState* OnOpenTag(const NGConstraintSpace&,
+                              const NGInlineItem&,
                               const NGInlineItemResult&,
                               FontBaseline baseline_type,
                               const NGLogicalLineItems&);
   // This variation adds a box placeholder to |line_box|.
-  NGInlineBoxState* OnOpenTag(const NGInlineItem&,
+  NGInlineBoxState* OnOpenTag(const NGConstraintSpace&,
+                              const NGInlineItem&,
                               const NGInlineItemResult&,
                               FontBaseline baseline_type,
                               NGLogicalLineItems* line_box);
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
index 2bde44a4..f87bbe665 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
@@ -87,8 +87,8 @@
     const NGInlineItemResult& item_result,
     NGLogicalLineItems* line_box,
     NGInlineLayoutStateStack* box_states) const {
-  NGInlineBoxState* box =
-      box_states->OnOpenTag(item, item_result, baseline_type_, line_box);
+  NGInlineBoxState* box = box_states->OnOpenTag(
+      ConstraintSpace(), item, item_result, baseline_type_, line_box);
   // Compute text metrics for all inline boxes since even empty inlines
   // influence the line height, except when quirks mode and the box is empty
   // for the purpose of empty block calculation.
@@ -577,8 +577,8 @@
   layout_object->SetIsTruncated(false);
 
   item_result->has_edge = true;
-  NGInlineBoxState* box =
-      box_states_->OnOpenTag(item, *item_result, baseline_type_, *line_box);
+  NGInlineBoxState* box = box_states_->OnOpenTag(
+      ConstraintSpace(), item, *item_result, baseline_type_, *line_box);
 
   if (LIKELY(!IsA<LayoutNGTextCombine>(layout_object))) {
     PlaceLayoutResult(item_result, line_box, box, box->margin_inline_start);
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 cadf13e..0346e37b 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
@@ -1856,6 +1856,7 @@
       DCHECK(container_builder_->Node().IsPaginatedRoot());
       DCHECK_EQ(node.Style().GetPosition(), EPosition::kFixed);
       builder.SetShouldRepeat(repeat_mode != kRepeatedLast);
+      builder.SetIsInsideRepeatableContent(true);
       is_repeatable = true;
     } else {
       SetupSpaceBuilderForFragmentation(
diff --git a/third_party/blink/renderer/core/loader/OWNERS b/third_party/blink/renderer/core/loader/OWNERS
index f8c53d1..a1e1bba 100644
--- a/third_party/blink/renderer/core/loader/OWNERS
+++ b/third_party/blink/renderer/core/loader/OWNERS
@@ -1,2 +1 @@
 japhet@chromium.org
-mkwst@chromium.org
diff --git a/third_party/blink/renderer/core/permissions_policy/policy_helper.h b/third_party/blink/renderer/core/permissions_policy/policy_helper.h
index dfb5331..b7012b1 100644
--- a/third_party/blink/renderer/core/permissions_policy/policy_helper.h
+++ b/third_party/blink/renderer/core/permissions_policy/policy_helper.h
@@ -63,7 +63,7 @@
 
 using DocumentPolicyFeatureSet = HashSet<
     mojom::blink::DocumentPolicyFeature,
-    DefaultHash<mojom::blink::DocumentPolicyFeature>::Hash,
+    DefaultHash<mojom::blink::DocumentPolicyFeature>,
     WTF::EnumOrGenericHashTraits<true, mojom::blink::DocumentPolicyFeature>>;
 
 class FeatureContext;
diff --git a/third_party/blink/renderer/core/style/computed_style_diff_functions.json5 b/third_party/blink/renderer/core/style/computed_style_diff_functions.json5
index 3dc7b220..f2d407016 100644
--- a/third_party/blink/renderer/core/style/computed_style_diff_functions.json5
+++ b/third_party/blink/renderer/core/style/computed_style_diff_functions.json5
@@ -87,6 +87,7 @@
                 "-webkit-border-horizontal-spacing",
                 "-webkit-border-vertical-spacing", "TextAutosizingMultiplier",
                 "ImplicitNamedGridColumnLines","ImplicitNamedGridRowLines", "NamedGridArea",
+                "initial-letter",
                 "grid-auto-rows", "grid-template-rows", "grid-template-columns",
                 "grid-auto-columns", "row-gap", "NamedGridAreaRowCount",
                 "NamedGridAreaColumnCount", "grid-auto-flow",
diff --git a/third_party/blink/renderer/core/svg/svg_element.cc b/third_party/blink/renderer/core/svg/svg_element.cc
index 59935fb..b1a17fe 100644
--- a/third_party/blink/renderer/core/svg/svg_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_element.cc
@@ -691,7 +691,7 @@
 
 using AttributeToPropertyTypeMap = HashMap<QualifiedName,
                                            AnimatedPropertyType,
-                                           DefaultHash<QualifiedName>::Hash,
+                                           DefaultHash<QualifiedName>,
                                            HashTraits<QualifiedName>,
                                            AnimatedPropertyTypeHashTraits>;
 AnimatedPropertyType SVGElement::AnimatedPropertyTypeForCSSAttribute(
diff --git a/third_party/blink/renderer/core/svg/svg_element.h b/third_party/blink/renderer/core/svg/svg_element.h
index b12bf35..ad50b62c 100644
--- a/third_party/blink/renderer/core/svg/svg_element.h
+++ b/third_party/blink/renderer/core/svg/svg_element.h
@@ -343,7 +343,7 @@
                                             key.NamespaceURI().Impl()};
       return HashComponents(components);
     }
-    return DefaultHash<QualifiedName>::Hash::GetHash(key);
+    return DefaultHash<QualifiedName>::GetHash(key);
   }
   static bool Equal(const QualifiedName& a, const QualifiedName& b) {
     return a.Matches(b);
diff --git a/third_party/blink/renderer/core/trustedtypes/OWNERS b/third_party/blink/renderer/core/trustedtypes/OWNERS
index 5440e48..956a3a5 100644
--- a/third_party/blink/renderer/core/trustedtypes/OWNERS
+++ b/third_party/blink/renderer/core/trustedtypes/OWNERS
@@ -1,2 +1 @@
-mkwst@chromium.org
 vogelheim@chromium.org
diff --git a/third_party/blink/renderer/core/url/OWNERS b/third_party/blink/renderer/core/url/OWNERS
deleted file mode 100644
index 3f84563..0000000
--- a/third_party/blink/renderer/core/url/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-mkwst@chromium.org
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc
index a09ebef..bb313f60 100644
--- a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc
+++ b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc
@@ -479,7 +479,11 @@
 }
 
 void DedicatedWorkerGlobalScope::UpdateBackForwardCacheDisablingFeatures(
-    uint64_t features_mask) {
+    uint64_t features_mask,
+    const BFCacheBlockingFeatureAndLocations&
+        non_sticky_features_and_js_locations,
+    const BFCacheBlockingFeatureAndLocations&
+        sticky_features_and_js_locations) {
   // `back_forward_cache_controller_host_` might not be bound when non-
   // PlzDedicatedWorker is used. Non-PlzDedicatedWorker will be removed in near
   // future.
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h
index 728d24ea..4feadd3 100644
--- a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h
+++ b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h
@@ -127,8 +127,12 @@
   bool IsOffMainThreadScriptFetchDisabled() override;
 
   // Implements scheduler::WorkerScheduler::Delegate.
-  void UpdateBackForwardCacheDisablingFeatures(uint64_t features_mask) override;
-
+  void UpdateBackForwardCacheDisablingFeatures(
+      uint64_t features_mask,
+      const BFCacheBlockingFeatureAndLocations&
+          non_sticky_features_and_js_locations,
+      const BFCacheBlockingFeatureAndLocations&
+          sticky_features_and_js_locations) override;
   // Implements BackForwardCacheLoaderHelperImpl::Delegate.
   void EvictFromBackForwardCache(
       mojom::blink::RendererEvictionReason reason) override;
diff --git a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h
index b7ab823..8a3e0b6 100644
--- a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h
+++ b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h
@@ -88,7 +88,11 @@
 
   // scheduler::WorkerScheduler::Delegate
   void UpdateBackForwardCacheDisablingFeatures(
-      uint64_t features_mask) override {}
+      uint64_t features_mask,
+      const BFCacheBlockingFeatureAndLocations&
+          non_sticky_features_and_js_locations,
+      const BFCacheBlockingFeatureAndLocations&
+          sticky_features_and_js_locations) override {}
 
   // BackForwardCacheLoaderHelperImpl::Delegate
   void EvictFromBackForwardCache(
diff --git a/third_party/blink/renderer/modules/BUILD.gn b/third_party/blink/renderer/modules/BUILD.gn
index a31ff3c..f3259e87 100644
--- a/third_party/blink/renderer/modules/BUILD.gn
+++ b/third_party/blink/renderer/modules/BUILD.gn
@@ -227,6 +227,7 @@
     "peerconnection/testing/mock_peer_connection_interface.h",
     "peerconnection/testing/mock_rtp_receiver.h",
     "peerconnection/testing/mock_rtp_sender.h",
+    "peerconnection/testing/mock_transformable_audio_frame.h",
     "peerconnection/testing/mock_transformable_video_frame.h",
     "permissions/testing/internals_permission.cc",
     "permissions/testing/internals_permission.h",
diff --git a/third_party/blink/renderer/modules/OWNERS b/third_party/blink/renderer/modules/OWNERS
index 4e16111..b26affc7 100644
--- a/third_party/blink/renderer/modules/OWNERS
+++ b/third_party/blink/renderer/modules/OWNERS
@@ -2,7 +2,6 @@
 haraken@chromium.org
 jbroman@chromium.org
 kinuko@chromium.org
-mkwst@chromium.org
 
 # Reviewers for inspector-related code:
 dgozman@chromium.org
diff --git a/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.cc b/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.cc
index 2a07272f..9b6c325 100644
--- a/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.cc
+++ b/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.cc
@@ -1297,26 +1297,18 @@
   }
 }
 
-void InspectorAccessibilityAgent::RetainAXContextForDocument(
+AXObjectCacheImpl& InspectorAccessibilityAgent::AttachToAXObjectCache(
     Document* document) {
+  DCHECK(document);
+  DCHECK(document->IsActive());
   if (!document_to_context_map_.Contains(document)) {
     auto context = std::make_unique<AXContext>(*document, ui::kAXModeComplete);
     document_to_context_map_.insert(document, std::move(context));
   }
-}
-
-AXObjectCacheImpl& InspectorAccessibilityAgent::GetAXObjectCacheImplForDocument(
-    Document* document) {
-  AXContext ax_context(*document, ui::kAXModeComplete);
-  return To<AXObjectCacheImpl>(ax_context.GetAXObjectCache());
-}
-
-AXObjectCacheImpl& InspectorAccessibilityAgent::AttachToAXObjectCache(
-    Document* document) {
-  RetainAXContextForDocument(document);
-  auto& cache = GetAXObjectCacheImplForDocument(document);
-  cache.AddInspectorAgent(this);
-  return cache;
+  AXObjectCacheImpl* cache =
+      To<AXObjectCacheImpl>(document->ExistingAXObjectCache());
+  cache->AddInspectorAgent(this);
+  return *cache;
 }
 
 void InspectorAccessibilityAgent::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.h b/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.h
index 634ad3b9..5cbe587 100644
--- a/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.h
+++ b/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.h
@@ -187,8 +187,6 @@
                    AXObjectCacheImpl&) const;
   LocalFrame* FrameFromIdOrRoot(const protocol::Maybe<String>& frame_id);
   void ScheduleAXChangeNotification(Document* document);
-  void RetainAXContextForDocument(Document* document);
-  AXObjectCacheImpl& GetAXObjectCacheImplForDocument(Document*);
   AXObjectCacheImpl& AttachToAXObjectCache(Document*);
   void ProcessPendingQueries(Document&);
   void ProcessPendingDirtyNodes(Document&);
diff --git a/third_party/blink/renderer/modules/file_system_access/file_system_handle.cc b/third_party/blink/renderer/modules/file_system_access/file_system_handle.cc
index 922a431..cf1d2ce 100644
--- a/third_party/blink/renderer/modules/file_system_access/file_system_handle.cc
+++ b/third_party/blink/renderer/modules/file_system_access/file_system_handle.cc
@@ -143,10 +143,8 @@
   auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise result = resolver->Promise();
 
-  String dest_name = new_entry_name.empty() ? name_ : new_entry_name;
-
   MoveImpl(
-      destination_directory->Transfer(), dest_name,
+      destination_directory->Transfer(), new_entry_name,
       WTF::BindOnce(
           [](FileSystemHandle* handle, const String& new_name,
              ScriptPromiseResolver* resolver, FileSystemAccessErrorPtr result) {
@@ -155,7 +153,7 @@
             }
             file_system_access_error::ResolveOrReject(resolver, *result);
           },
-          WrapPersistent(this), dest_name, WrapPersistent(resolver)));
+          WrapPersistent(this), new_entry_name, WrapPersistent(resolver)));
 
   return result;
 }
diff --git a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc
index c93a697..525d2f68 100644
--- a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc
+++ b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc
@@ -448,7 +448,7 @@
         attributes, &info, KURL("chrome://VideoTrackRecorderImpl"));
 
     if (encoder_thread_context_ &&
-        !encoder_thread_context_->BindToCurrentThread()) {
+        !encoder_thread_context_->BindToCurrentSequence()) {
       encoder_thread_context_ = nullptr;
     }
   }
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
index 01b3e059..2754276 100644
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
@@ -13,6 +13,7 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
@@ -158,7 +159,7 @@
       void(scoped_refptr<media::VideoFrame> frame, bool is_copy)>;
   FrameDeliverer(const base::WeakPtr<WebMediaPlayerMS>& player,
                  RepaintCB enqueue_frame_cb,
-                 scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+                 scoped_refptr<base::SequencedTaskRunner> media_task_runner,
                  scoped_refptr<base::TaskRunner> worker_task_runner,
                  media::GpuVideoAcceleratorFactories* gpu_factories)
       : main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
@@ -325,7 +326,7 @@
 
   // Pool of GpuMemoryBuffers and resources used to create hardware frames.
   std::unique_ptr<media::GpuMemoryBufferVideoFramePool> gpu_memory_buffer_pool_;
-  const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+  const scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
   const scoped_refptr<base::TaskRunner> worker_task_runner_;
 
   media::GpuVideoAcceleratorFactories* const gpu_factories_;
@@ -345,7 +346,7 @@
     scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
-    scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+    scoped_refptr<base::SequencedTaskRunner> media_task_runner,
     scoped_refptr<base::TaskRunner> worker_task_runner,
     media::GpuVideoAcceleratorFactories* gpu_factories,
     const WebString& sink_id,
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 dca8648..49c3f946 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
@@ -192,8 +192,8 @@
   // Calculate the output size in double precision floating point number that
   // ensures all dimension values of type uint32_t can be exactly represented.
   // https://en.wikipedia.org/wiki/Double-precision_floating-point_format#Precision_limitations_on_integer_values
-  // The max value of checked_output_size should be 3 * UINT_MAX + 1, assert it
-  // is less than max integer value of double type.
+  // The max value of checked_output_size should be 3 * UINT_MAX + 1,
+  // which is smaller than the max safe integer value for double type.
   auto checked_output_size =
       (base::MakeCheckedNum<double>(input_size) -
        checked_effective_filter_size + beginning_padding + ending_padding) /
diff --git a/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.cc b/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.cc
index 896a0df..d0488ac 100644
--- a/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.cc
+++ b/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.cc
@@ -584,10 +584,4 @@
                : webrtc::RTCError(webrtc::RTCErrorType::UNSUPPORTED_OPERATION));
 }
 
-webrtc::RTCError MockPeerConnectionImpl::SetBitrate(
-    const webrtc::BitrateSettings& bitrate) {
-  NOTIMPLEMENTED();
-  return webrtc::RTCError::OK();
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h b/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h
index 93a80fd..237bce3 100644
--- a/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h
+++ b/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h
@@ -16,6 +16,7 @@
 #include "third_party/webrtc/api/peer_connection_interface.h"
 #include "third_party/webrtc/api/sctp_transport_interface.h"
 #include "third_party/webrtc/api/stats/rtc_stats_report.h"
+#include "third_party/webrtc/api/test/mock_peerconnectioninterface.h"
 
 namespace blink {
 
@@ -174,7 +175,7 @@
 // this. It introduces complexity, is error prone (not testing the right thing
 // and bugs in the mocks). This class is a maintenance burden and should be
 // removed. https://crbug.com/788659
-class MockPeerConnectionImpl : public webrtc::PeerConnectionInterface {
+class MockPeerConnectionImpl : public webrtc::MockPeerConnectionInterface {
  public:
   explicit MockPeerConnectionImpl(MockPeerConnectionDependencyFactory* factory,
                                   webrtc::PeerConnectionObserver* observer);
@@ -182,60 +183,6 @@
   MockPeerConnectionImpl(const MockPeerConnectionImpl&) = delete;
   MockPeerConnectionImpl& operator=(const MockPeerConnectionImpl&) = delete;
 
-  // PeerConnectionInterface implementation.
-  rtc::scoped_refptr<webrtc::StreamCollectionInterface> local_streams()
-      override {
-    NOTIMPLEMENTED();
-    return nullptr;
-  }
-  rtc::scoped_refptr<webrtc::StreamCollectionInterface> remote_streams()
-      override {
-    NOTIMPLEMENTED();
-    return nullptr;
-  }
-  bool AddStream(webrtc::MediaStreamInterface* local_stream) override {
-    NOTIMPLEMENTED();
-    return false;
-  }
-  void RemoveStream(webrtc::MediaStreamInterface* local_stream) override {
-    NOTIMPLEMENTED();
-  }
-  webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
-  AddTransceiver(
-      rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track) override {
-    NOTIMPLEMENTED();
-    return webrtc::RTCErrorOr<
-        rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>();
-  }
-  webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
-  AddTransceiver(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track,
-                 const webrtc::RtpTransceiverInit& init) override {
-    NOTIMPLEMENTED();
-    return webrtc::RTCErrorOr<
-        rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>();
-  }
-
-  webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
-  AddTransceiver(cricket::MediaType media_type) override {
-    NOTIMPLEMENTED();
-    return webrtc::RTCErrorOr<
-        rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>();
-  }
-  webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
-  AddTransceiver(cricket::MediaType media_type,
-                 const webrtc::RtpTransceiverInit& init) override {
-    NOTIMPLEMENTED();
-    return webrtc::RTCErrorOr<
-        rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>();
-  }
-
-  rtc::scoped_refptr<webrtc::RtpSenderInterface> CreateSender(
-      const std::string& kind,
-      const std::string& stream_id) override {
-    NOTIMPLEMENTED();
-    return nullptr;
-  }
-
   webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> AddTrack(
       rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track,
       const std::vector<std::string>& stream_ids) override;
@@ -273,41 +220,6 @@
     return nullptr;
   }
 
-  SignalingState signaling_state() override {
-    NOTIMPLEMENTED();
-    return PeerConnectionInterface::kStable;
-  }
-  IceConnectionState ice_connection_state() override {
-    NOTIMPLEMENTED();
-    return PeerConnectionInterface::kIceConnectionNew;
-  }
-  IceConnectionState standardized_ice_connection_state() override {
-    NOTIMPLEMENTED();
-    return PeerConnectionInterface::kIceConnectionNew;
-  }
-
-  PeerConnectionState peer_connection_state() override {
-    NOTIMPLEMENTED();
-    return PeerConnectionState::kNew;
-  }
-
-  IceGatheringState ice_gathering_state() override {
-    NOTIMPLEMENTED();
-    return PeerConnectionInterface::kIceGatheringNew;
-  }
-
-  bool StartRtcEventLog(std::unique_ptr<webrtc::RtcEventLogOutput> output,
-                        int64_t output_period_ms) override {
-    NOTIMPLEMENTED();
-    return false;
-  }
-  bool StartRtcEventLog(
-      std::unique_ptr<webrtc::RtcEventLogOutput> output) override {
-    NOTIMPLEMENTED();
-    return false;
-  }
-  void StopRtcEventLog() override { NOTIMPLEMENTED(); }
-
   MOCK_METHOD0(Close, void());
 
   const webrtc::SessionDescriptionInterface* local_description() const override;
@@ -330,8 +242,6 @@
     return nullptr;
   }
 
-  void RestartIce() override { NOTIMPLEMENTED(); }
-
   // JSEP01 APIs
   void CreateOffer(webrtc::CreateSessionDescriptionObserver* observer,
                    const RTCOfferAnswerOptions& options) override;
@@ -375,25 +285,12 @@
   void SetRemoteDescriptionWorker(
       webrtc::SetSessionDescriptionObserver* observer,
       webrtc::SessionDescriptionInterface* desc);
-  webrtc::PeerConnectionInterface::RTCConfiguration GetConfiguration()
-      override {
-    NOTIMPLEMENTED();
-    return webrtc::PeerConnectionInterface::RTCConfiguration();
-  }
   webrtc::RTCError SetConfiguration(
       const RTCConfiguration& configuration) override;
 
   bool AddIceCandidate(const webrtc::IceCandidateInterface* candidate) override;
   void AddIceCandidate(std::unique_ptr<webrtc::IceCandidateInterface> candidate,
                        std::function<void(webrtc::RTCError)> callback) override;
-  bool RemoveIceCandidates(
-      const std::vector<cricket::Candidate>& candidates) override {
-    NOTIMPLEMENTED();
-    return false;
-  }
-
-  webrtc::RTCError SetBitrate(const webrtc::BitrateSettings& bitrate) override;
-
   void AddRemoteStream(webrtc::MediaStreamInterface* stream);
 
   const std::string& stream_label() const { return stream_label_; }
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.cc b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.cc
index 12f433e..ab716a3 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.cc
@@ -25,12 +25,7 @@
         webrtc_audio_frame) {
   Vector<uint32_t> contributing_sources;
   if (webrtc_audio_frame) {
-    wtf_size_t num_csrcs = webrtc_audio_frame->GetHeader().numCSRCs;
-    contributing_sources.ReserveInitialCapacity(num_csrcs);
-    for (wtf_size_t i = 0; i < num_csrcs; i++) {
-      contributing_sources.push_back(
-          webrtc_audio_frame->GetHeader().arrOfCSRCs[i]);
-    }
+    contributing_sources.assign(webrtc_audio_frame->GetContributingSources());
   }
   delegate_ = base::MakeRefCounted<RTCEncodedAudioFrameDelegate>(
       std::move(webrtc_audio_frame), std::move(contributing_sources));
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_receiver_sink_optimizer.cc b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_receiver_sink_optimizer.cc
index 0aaa999..84a4c58 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_receiver_sink_optimizer.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_receiver_sink_optimizer.cc
@@ -1,3 +1,7 @@
+// Copyright 2021 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
 #include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_receiver_sink_optimizer.h"
 #include "third_party/blink/renderer/platform/heap/cross_thread_persistent.h"
 #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
@@ -15,7 +19,8 @@
 RtcEncodedAudioReceiverSinkOptimizer::PerformInProcessOptimization(
     ScriptState* script_state) {
   auto* new_sink = MakeGarbageCollected<RTCEncodedAudioUnderlyingSink>(
-      script_state, std::move(transformer_));
+      script_state, std::move(transformer_),
+      webrtc::TransformableFrameInterface::Direction::kReceiver);
 
   std::move(set_underlying_sink_).Run(WrapCrossThreadPersistent(new_sink));
 
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_receiver_source_optimizer.cc b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_receiver_source_optimizer.cc
index 2858583..99c6c961 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_receiver_source_optimizer.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_receiver_source_optimizer.cc
@@ -1,3 +1,7 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
 #include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_receiver_source_optimizer.h"
 #include "third_party/blink/renderer/platform/heap/cross_thread_persistent.h"
 #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_sender_sink_optimizer.cc b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_sender_sink_optimizer.cc
index dbf9184e..372f6f3 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_sender_sink_optimizer.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_sender_sink_optimizer.cc
@@ -19,7 +19,8 @@
 RtcEncodedAudioSenderSinkOptimizer::PerformInProcessOptimization(
     ScriptState* script_state) {
   auto* new_sink = MakeGarbageCollected<RTCEncodedAudioUnderlyingSink>(
-      script_state, std::move(transformer_));
+      script_state, std::move(transformer_),
+      webrtc::TransformableFrameInterface::Direction::kSender);
 
   std::move(set_underlying_sink_).Run(WrapCrossThreadPersistent(new_sink));
 
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.cc b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.cc
index 12d7e782..74f9957 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.cc
@@ -16,8 +16,10 @@
 RTCEncodedAudioUnderlyingSink::RTCEncodedAudioUnderlyingSink(
     ScriptState* script_state,
     scoped_refptr<blink::RTCEncodedAudioStreamTransformer::Broker>
-        transformer_broker)
-    : transformer_broker_(std::move(transformer_broker)) {
+        transformer_broker,
+    webrtc::TransformableFrameInterface::Direction expected_direction)
+    : transformer_broker_(std::move(transformer_broker)),
+      expected_direction_(expected_direction) {
   DCHECK(transformer_broker_);
 }
 
@@ -56,6 +58,12 @@
     return ScriptPromise();
   }
 
+  if (webrtc_frame->GetDirection() != expected_direction_) {
+    exception_state.ThrowDOMException(DOMExceptionCode::kOperationError,
+                                      "Invalid frame");
+    return ScriptPromise();
+  }
+
   transformer_broker_->SendFrameToSink(std::move(webrtc_frame));
   return ScriptPromise::CastUndefined(script_state);
 }
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.h b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.h
index 400d2553..52f2c0e 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.h
@@ -9,6 +9,7 @@
 #include "third_party/blink/renderer/core/streams/underlying_sink_base.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
 #include "third_party/blink/renderer/platform/peerconnection/rtc_encoded_audio_stream_transformer.h"
+#include "third_party/webrtc/api/frame_transformer_interface.h"
 
 namespace blink {
 
@@ -20,7 +21,8 @@
  public:
   RTCEncodedAudioUnderlyingSink(
       ScriptState*,
-      scoped_refptr<blink::RTCEncodedAudioStreamTransformer::Broker>);
+      scoped_refptr<blink::RTCEncodedAudioStreamTransformer::Broker>,
+      webrtc::TransformableFrameInterface::Direction);
 
   // UnderlyingSinkBase
   ScriptPromise start(ScriptState*,
@@ -40,6 +42,7 @@
  private:
   scoped_refptr<blink::RTCEncodedAudioStreamTransformer::Broker>
       transformer_broker_;
+  webrtc::TransformableFrameInterface::Direction expected_direction_;
   THREAD_CHECKER(thread_checker_);
 };
 
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink_test.cc b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink_test.cc
index 84f29da..cb4fd6d 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink_test.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink_test.cc
@@ -11,19 +11,26 @@
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_tester.h"
 #include "third_party/blink/renderer/bindings/core/v8/to_v8_traits.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_rtc_encoded_audio_frame.h"
+#include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/core/streams/writable_stream.h"
 #include "third_party/blink/renderer/core/streams/writable_stream_default_writer.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"
+#include "third_party/blink/renderer/modules/peerconnection/testing/mock_transformable_audio_frame.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/peerconnection/rtc_encoded_audio_stream_transformer.h"
 #include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 #include "third_party/webrtc/api/frame_transformer_interface.h"
 #include "third_party/webrtc/api/scoped_refptr.h"
 #include "third_party/webrtc/rtc_base/ref_counted_object.h"
 
 using testing::_;
+using testing::NiceMock;
+using testing::Return;
 
 namespace blink {
 
@@ -71,16 +78,27 @@
     EXPECT_FALSE(transformer_.HasTransformedFrameCallback());
   }
 
-  RTCEncodedAudioUnderlyingSink* CreateSink(ScriptState* script_state) {
+  RTCEncodedAudioUnderlyingSink* CreateSink(
+      ScriptState* script_state,
+      webrtc::TransformableFrameInterface::Direction expected_direction =
+          webrtc::TransformableFrameInterface::Direction::kSender) {
     return MakeGarbageCollected<RTCEncodedAudioUnderlyingSink>(
-        script_state, transformer_.GetBroker());
+        script_state, transformer_.GetBroker(), expected_direction);
   }
 
   RTCEncodedAudioStreamTransformer* GetTransformer() { return &transformer_; }
 
-  ScriptValue CreateEncodedAudioFrameChunk(ScriptState* script_state) {
-    RTCEncodedAudioFrame* frame = MakeGarbageCollected<RTCEncodedAudioFrame>(
-        std::make_unique<FakeAudioFrame>());
+  ScriptValue CreateEncodedAudioFrameChunk(
+      ScriptState* script_state,
+      webrtc::TransformableFrameInterface::Direction direction =
+          webrtc::TransformableFrameInterface::Direction::kSender) {
+    auto mock_frame = std::make_unique<NiceMock<MockTransformableAudioFrame>>();
+    ON_CALL(*mock_frame.get(), GetDirection).WillByDefault(Return(direction));
+    std::unique_ptr<webrtc::TransformableAudioFrameInterface> audio_frame =
+        base::WrapUnique(static_cast<webrtc::TransformableAudioFrameInterface*>(
+            mock_frame.release()));
+    RTCEncodedAudioFrame* frame =
+        MakeGarbageCollected<RTCEncodedAudioFrame>(std::move(audio_frame));
     return ScriptValue(
         script_state->GetIsolate(),
         ToV8Traits<RTCEncodedAudioFrame>::ToV8(script_state, frame)
@@ -139,4 +157,21 @@
   EXPECT_TRUE(dummy_exception_state.HadException());
 }
 
+TEST_F(RTCEncodedAudioUnderlyingSinkTest, WriteInvalidDirectionFails) {
+  V8TestingScope v8_scope;
+  ScriptState* script_state = v8_scope.GetScriptState();
+  auto* sink = CreateSink(
+      script_state, webrtc::TransformableFrameInterface::Direction::kSender);
+
+  // Write an encoded chunk with direction set to Receiver should fail as it
+  // doesn't match the expected direction of our sink.
+  DummyExceptionStateForTesting dummy_exception_state;
+  sink->write(script_state,
+              CreateEncodedAudioFrameChunk(
+                  script_state,
+                  webrtc::TransformableFrameInterface::Direction::kReceiver),
+              nullptr, dummy_exception_state);
+  EXPECT_TRUE(dummy_exception_state.HadException());
+}
+
 }  // namespace blink
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 746554b..ff48c27 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
@@ -425,7 +425,8 @@
     // Set up writable.
     audio_to_decoder_underlying_sink_ =
         MakeGarbageCollected<RTCEncodedAudioUnderlyingSink>(
-            script_state, encoded_audio_transformer_);
+            script_state, encoded_audio_transformer_,
+            webrtc::TransformableFrameInterface::Direction::kReceiver);
 
     auto set_underlying_sink =
         WTF::CrossThreadBindOnce(&RTCRtpReceiver::SetAudioUnderlyingSink,
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 283d2b4..3d8881e4 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
@@ -900,7 +900,8 @@
     // Set up writable.
     audio_to_packetizer_underlying_sink_ =
         MakeGarbageCollected<RTCEncodedAudioUnderlyingSink>(
-            script_state, encoded_audio_transformer_);
+            script_state, encoded_audio_transformer_,
+            webrtc::TransformableFrameInterface::Direction::kSender);
 
     auto set_underlying_sink =
         WTF::CrossThreadBindOnce(&RTCRtpSender::SetAudioUnderlyingSink,
diff --git a/third_party/blink/renderer/modules/peerconnection/testing/mock_transformable_audio_frame.h b/third_party/blink/renderer/modules/peerconnection/testing/mock_transformable_audio_frame.h
new file mode 100644
index 0000000..af227a3
--- /dev/null
+++ b/third_party/blink/renderer/modules/peerconnection/testing/mock_transformable_audio_frame.h
@@ -0,0 +1,35 @@
+// 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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_TESTING_MOCK_TRANSFORMABLE_AUDIO_FRAME_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_TESTING_MOCK_TRANSFORMABLE_AUDIO_FRAME_H_
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "third_party/webrtc/api/array_view.h"
+#include "third_party/webrtc/api/frame_transformer_interface.h"
+
+namespace blink {
+
+class MockTransformableAudioFrame
+    : public webrtc::TransformableAudioFrameInterface {
+ public:
+  MOCK_METHOD(rtc::ArrayView<const uint8_t>, GetData, (), (const override));
+  MOCK_METHOD(void, SetData, (rtc::ArrayView<const uint8_t> data), (override));
+  MOCK_METHOD(uint8_t, GetPayloadType, (), (const, override));
+  MOCK_METHOD(uint32_t, GetSsrc, (), (const, override));
+  MOCK_METHOD(uint32_t, GetTimestamp, (), (const override));
+  MOCK_METHOD(const webrtc::RTPHeader&, GetHeader, (), (const override));
+  MOCK_METHOD(rtc::ArrayView<const uint32_t>,
+              GetContributingSources,
+              (),
+              (const override));
+  MOCK_METHOD(webrtc::TransformableFrameInterface::Direction,
+              GetDirection,
+              (),
+              (const, override));
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_TESTING_MOCK_TRANSFORMABLE_AUDIO_FRAME_H_
diff --git a/third_party/blink/renderer/modules/webaudio/offline_audio_context.h b/third_party/blink/renderer/modules/webaudio/offline_audio_context.h
index 9e6f29c0..7b076fc 100644
--- a/third_party/blink/renderer/modules/webaudio/offline_audio_context.h
+++ b/third_party/blink/renderer/modules/webaudio/offline_audio_context.h
@@ -96,7 +96,7 @@
   // zero.
   using SuspendMap = HeapHashMap<size_t,
                                  Member<ScriptPromiseResolver>,
-                                 DefaultHash<size_t>::Hash,
+                                 DefaultHash<size_t>,
                                  WTF::UnsignedWithZeroKeyHashTraits<size_t>>;
 
   using OfflineGraphAutoLocker = DeferredTaskHandler::OfflineGraphAutoLocker;
@@ -127,7 +127,7 @@
   // Holds copies of `quantized_frame` in `scheduled_suspends_` to ensure
   // a safe access from the audio thread.
   HashSet<size_t,
-          WTF::DefaultHash<size_t>::Hash,
+          WTF::DefaultHash<size_t>,
           WTF::UnsignedWithZeroKeyHashTraits<size_t>>
       scheduled_suspend_frames_ GUARDED_BY(suspend_frames_lock_);
 
diff --git a/third_party/blink/renderer/modules/webcodecs/background_readback.cc b/third_party/blink/renderer/modules/webcodecs/background_readback.cc
index a2973c9e..01c097c0 100644
--- a/third_party/blink/renderer/modules/webcodecs/background_readback.cc
+++ b/third_party/blink/renderer/modules/webcodecs/background_readback.cc
@@ -195,7 +195,7 @@
     return false;
   }
 
-  if (!context_provider_->BindToCurrentThread()) {
+  if (!context_provider_->BindToCurrentSequence()) {
     DLOG(ERROR) << "Can't bind context provider.";
     context_provider_ = nullptr;
     return false;
diff --git a/third_party/blink/renderer/modules/webcodecs/image_decoder_core.h b/third_party/blink/renderer/modules/webcodecs/image_decoder_core.h
index 6cbf645..cbc06548 100644
--- a/third_party/blink/renderer/modules/webcodecs/image_decoder_core.h
+++ b/third_party/blink/renderer/modules/webcodecs/image_decoder_core.h
@@ -138,7 +138,7 @@
   // resolution of promises until a new bitmap is generated.
   HashMap<uint32_t,
           uint32_t,
-          DefaultHash<uint32_t>::Hash,
+          DefaultHash<uint32_t>,
           WTF::UnsignedWithZeroKeyHashTraits<uint32_t>>
       incomplete_frames_;
 
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
index 8fbce131..faa19d5 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
@@ -549,9 +549,9 @@
     context_provider = CreateContextProviderOnWorkerThread(context_attributes,
                                                            graphics_info, url);
   }
-  if (context_provider && !context_provider->BindToCurrentThread()) {
+  if (context_provider && !context_provider->BindToCurrentSequence()) {
     context_provider = nullptr;
-    graphics_info->error_message = String("bindToCurrentThread failed: " +
+    graphics_info->error_message = String("BindToCurrentSequence failed: " +
                                           String(graphics_info->error_message));
   }
   if (!context_provider || g_should_fail_context_creation_for_testing) {
@@ -8521,7 +8521,7 @@
         CreateContextProviderOnWorkerThread(attributes, &gl_info, url);
   }
   scoped_refptr<DrawingBuffer> buffer;
-  if (context_provider && context_provider->BindToCurrentThread()) {
+  if (context_provider && context_provider->BindToCurrentSequence()) {
     // Construct a new drawing buffer with the new GL context.
     buffer = CreateDrawingBuffer(std::move(context_provider), gl_info);
     // If DrawingBuffer::create() fails to allocate a fbo, |drawingBuffer| is
diff --git a/third_party/blink/renderer/modules/webgl/webgl_webcodecs_video_frame.cc b/third_party/blink/renderer/modules/webgl/webgl_webcodecs_video_frame.cc
index cea7063..a608580 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_webcodecs_video_frame.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl_webcodecs_video_frame.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/modules/webgl/webgl_webcodecs_video_frame.h"
 
 #include "base/synchronization/waitable_event.h"
+#include "base/task/sequenced_task_runner.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "media/base/wait_and_replace_sync_token_client.h"
@@ -39,7 +40,7 @@
 #endif
 
 void GetMediaTaskRunnerAndGpuFactoriesOnMainThread(
-    scoped_refptr<base::SingleThreadTaskRunner>* media_task_runner_out,
+    scoped_refptr<base::SequencedTaskRunner>* media_task_runner_out,
     media::GpuVideoAcceleratorFactories** gpu_factories_out,
     base::WaitableEvent* waitable_event) {
   DCHECK(IsMainThread());
diff --git a/third_party/blink/renderer/modules/webgl/webgl_webcodecs_video_frame.h b/third_party/blink/renderer/modules/webgl/webgl_webcodecs_video_frame.h
index 94474aa..0a0e8e5b 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_webcodecs_video_frame.h
+++ b/third_party/blink/renderer/modules/webgl/webgl_webcodecs_video_frame.h
@@ -64,7 +64,7 @@
 
   std::unique_ptr<media::GpuMemoryBufferVideoFramePool> gpu_memory_buffer_pool_;
   scoped_refptr<base::SequencedTaskRunner> worker_task_runner_;
-  scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+  scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
   scoped_refptr<media::VideoFrame> hardware_video_frame_;
 };
 
diff --git a/third_party/blink/renderer/modules/webgpu/gpu.cc b/third_party/blink/renderer/modules/webgpu/gpu.cc
index 488030c..672a82f 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu.cc
@@ -100,8 +100,8 @@
   }
 
   // TODO(kainino): we will need a better way of accessing the GPU interface
-  // from multiple threads than BindToCurrentThread et al.
-  if (context_provider && !context_provider->BindToCurrentThread()) {
+  // from multiple threads than BindToCurrentSequence et al.
+  if (context_provider && !context_provider->BindToCurrentSequence()) {
     // TODO(crbug.com/973017): Collect GPU info and surface context creation
     // error.
     return nullptr;
diff --git a/third_party/blink/renderer/modules/webtransport/web_transport.h b/third_party/blink/renderer/modules/webtransport/web_transport.h
index 0d324e62..ce9e8ca9 100644
--- a/third_party/blink/renderer/modules/webtransport/web_transport.h
+++ b/third_party/blink/renderer/modules/webtransport/web_transport.h
@@ -168,7 +168,7 @@
   // TODO(ricea): Find out if such large stream ids are possible.
   HeapHashMap<uint32_t,
               Member<IncomingStream>,
-              WTF::DefaultHash<uint32_t>::Hash,
+              WTF::DefaultHash<uint32_t>,
               WTF::UnsignedWithZeroKeyHashTraits<uint32_t>>
       incoming_stream_map_;
 
@@ -178,7 +178,7 @@
   // TODO(ricea): Find out if such large stream ids are possible.
   HeapHashMap<uint32_t,
               Member<OutgoingStream>,
-              WTF::DefaultHash<uint32_t>::Hash,
+              WTF::DefaultHash<uint32_t>,
               WTF::UnsignedWithZeroKeyHashTraits<uint32_t>>
       outgoing_stream_map_;
 
@@ -187,7 +187,7 @@
   // corresponding incoming stream, the event is recorded here.
   HashMap<uint32_t,
           bool,
-          WTF::DefaultHash<uint32_t>::Hash,
+          WTF::DefaultHash<uint32_t>,
           WTF::UnsignedWithZeroKeyHashTraits<uint32_t>>
       closed_potentially_pending_streams_;
 
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn
index 2aee75c..b1406b8 100644
--- a/third_party/blink/renderer/platform/BUILD.gn
+++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -1129,6 +1129,8 @@
     "image-decoders/bmp/bmp_image_decoder.h",
     "image-decoders/bmp/bmp_image_reader.cc",
     "image-decoders/bmp/bmp_image_reader.h",
+    "image-decoders/exif_reader.cc",
+    "image-decoders/exif_reader.h",
     "image-decoders/fast_shared_buffer_reader.cc",
     "image-decoders/fast_shared_buffer_reader.h",
     "image-decoders/gif/gif_image_decoder.cc",
diff --git a/third_party/blink/renderer/platform/OWNERS b/third_party/blink/renderer/platform/OWNERS
index d35f1e2d..8516343 100644
--- a/third_party/blink/renderer/platform/OWNERS
+++ b/third_party/blink/renderer/platform/OWNERS
@@ -11,7 +11,6 @@
 kbr@chromium.org
 kinuko@chromium.org
 kojii@chromium.org
-mkwst@chromium.org
 noel@chromium.org
 pdr@chromium.org
 schenney@chromium.org
diff --git a/third_party/blink/renderer/platform/crypto.h b/third_party/blink/renderer/platform/crypto.h
index 863c369..cec17a52 100644
--- a/third_party/blink/renderer/platform/crypto.h
+++ b/third_party/blink/renderer/platform/crypto.h
@@ -65,21 +65,13 @@
   static const bool safe_to_compare_to_empty_or_deleted = true;
 };
 template <>
-struct DefaultHash<blink::DigestValue> {
-  STATIC_ONLY(DefaultHash);
-  typedef DigestValueHash Hash;
-};
+struct DefaultHash<blink::DigestValue> : DigestValueHash {};
 
 template <>
-struct DefaultHash<blink::HashAlgorithm> {
-  STATIC_ONLY(DefaultHash);
-  typedef IntHash<blink::HashAlgorithm> Hash;
-};
+struct DefaultHash<blink::HashAlgorithm> : IntHash<blink::HashAlgorithm> {};
 template <>
 struct HashTraits<blink::HashAlgorithm>
-    : UnsignedWithZeroKeyHashTraits<blink::HashAlgorithm> {
-  STATIC_ONLY(HashTraits);
-};
+    : UnsignedWithZeroKeyHashTraits<blink::HashAlgorithm> {};
 
 }  // namespace WTF
 
diff --git a/third_party/blink/renderer/platform/fonts/font_cache_key.h b/third_party/blink/renderer/platform/fonts/font_cache_key.h
index e75a3ecc..40da44414 100644
--- a/third_party/blink/renderer/platform/fonts/font_cache_key.h
+++ b/third_party/blink/renderer/platform/fonts/font_cache_key.h
@@ -167,16 +167,11 @@
 
 namespace WTF {
 template <>
-struct DefaultHash<blink::FontCacheKey> {
-  STATIC_ONLY(DefaultHash);
-  typedef blink::FontCacheKeyHash Hash;
-};
+struct DefaultHash<blink::FontCacheKey> : blink::FontCacheKeyHash {};
 
 template <>
 struct HashTraits<blink::FontCacheKey>
     : WTF::SimpleClassHashTraits<blink::FontCacheKey> {
-  STATIC_ONLY(HashTraits);
-
   // std::string's empty state need not be zero in all implementations,
   // and it is held within FontFaceCreationParams.
   static const bool kEmptyValueIsZero = false;
diff --git a/third_party/blink/renderer/platform/fonts/font_description.h b/third_party/blink/renderer/platform/fonts/font_description.h
index 9167d5d..4964975 100644
--- a/third_party/blink/renderer/platform/fonts/font_description.h
+++ b/third_party/blink/renderer/platform/fonts/font_description.h
@@ -543,14 +543,18 @@
   static bool use_subpixel_text_positioning_;
 };
 
-struct FontDescriptionHash {
-  STATIC_ONLY(FontDescriptionHash);
+}  // namespace blink
 
-  static unsigned GetHash(const FontDescription& description) {
+namespace WTF {
+
+template <>
+struct DefaultHash<blink::FontDescription> {
+  static unsigned GetHash(const blink::FontDescription& description) {
     return description.GetHash();
   }
 
-  static bool Equal(const FontDescription& a, const FontDescription& b) {
+  static bool Equal(const blink::FontDescription& a,
+                    const blink::FontDescription& b) {
     return a == b;
   }
 
@@ -559,17 +563,6 @@
   static const bool safe_to_compare_to_empty_or_deleted = true;
 };
 
-}  // namespace blink
-
-namespace WTF {
-
-template <typename T>
-struct DefaultHash;
-template <>
-struct DefaultHash<blink::FontDescription> {
-  using Hash = blink::FontDescriptionHash;
-};
-
 template <typename T>
 struct HashTraits;
 template <>
diff --git a/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc b/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc
index faf80c0..7eca28bb 100644
--- a/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc
+++ b/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc
@@ -33,6 +33,22 @@
 
 namespace blink {
 
+namespace {
+
+bool IdentifiabilityStudyShouldSampleFonts() {
+  return IdentifiabilityStudySettings::Get()->ShouldSampleAnyType({
+      IdentifiableSurface::Type::kLocalFontLookupByUniqueOrFamilyName,
+      IdentifiableSurface::Type::kLocalFontLookupByUniqueNameOnly,
+      IdentifiableSurface::Type::kLocalFontLookupByFallbackCharacter,
+      IdentifiableSurface::Type::kLocalFontLookupAsLastResort,
+      IdentifiableSurface::Type::kGenericFontLookup,
+      IdentifiableSurface::Type::kLocalFontLoadPostScriptName,
+      IdentifiableSurface::Type::kLocalFontExistenceByUniqueNameOnly,
+  });
+}
+
+}  // namespace
+
 FontMatchingMetrics::FontMatchingMetrics(
     bool top_level,
     ukm::UkmRecorder* ukm_recorder,
@@ -116,7 +132,7 @@
 void FontMatchingMetrics::InsertFontHashIntoMap(IdentifiableTokenKey input_key,
                                                 SimpleFontData* font_data,
                                                 TokenToTokenHashMap& hash_map) {
-  DCHECK(IdentifiabilityStudySettings::Get()->IsActive());
+  DCHECK(IdentifiabilityStudyShouldSampleFonts());
   if (hash_map.Contains(input_key))
     return;
   IdentifiableToken output_token(GetHashForFontData(font_data));
@@ -269,7 +285,7 @@
 }
 
 void FontMatchingMetrics::PublishIdentifiabilityMetrics() {
-  if (!IdentifiabilityStudySettings::Get()->IsActive())
+  if (!IdentifiabilityStudyShouldSampleFonts())
     return;
 
   IdentifiabilityMetricBuilder builder(source_id_);
@@ -349,7 +365,7 @@
 }
 
 void FontMatchingMetrics::OnFontLookup() {
-  DCHECK(IdentifiabilityStudySettings::Get()->IsActive());
+  DCHECK(IdentifiabilityStudyShouldSampleFonts());
   if (!identifiability_metrics_timer_.IsActive()) {
     identifiability_metrics_timer_.StartOneShot(base::Minutes(1), FROM_HERE);
   }
diff --git a/third_party/blink/renderer/platform/fonts/font_selection_types.h b/third_party/blink/renderer/platform/fonts/font_selection_types.h
index c9d5d8ac..cd9ced7 100644
--- a/third_party/blink/renderer/platform/fonts/font_selection_types.h
+++ b/third_party/blink/renderer/platform/fonts/font_selection_types.h
@@ -484,16 +484,12 @@
 namespace WTF {
 
 template <>
-struct DefaultHash<blink::FontSelectionCapabilities> {
-  STATIC_ONLY(DefaultHash);
-  typedef blink::FontSelectionCapabilitiesHash Hash;
-};
+struct DefaultHash<blink::FontSelectionCapabilities>
+    : blink::FontSelectionCapabilitiesHash {};
 
 template <>
 struct HashTraits<blink::FontSelectionCapabilities>
-    : SimpleClassHashTraits<blink::FontSelectionCapabilities> {
-  STATIC_ONLY(HashTraits);
-};
+    : SimpleClassHashTraits<blink::FontSelectionCapabilities> {};
 
 }  // namespace WTF
 
diff --git a/third_party/blink/renderer/platform/fonts/generic_font_family_settings.h b/third_party/blink/renderer/platform/fonts/generic_font_family_settings.h
index 26bad06..01f1b5d0 100644
--- a/third_party/blink/renderer/platform/fonts/generic_font_family_settings.h
+++ b/third_party/blink/renderer/platform/fonts/generic_font_family_settings.h
@@ -87,10 +87,7 @@
     static bool IsDeletedValue(int value) { return value == -3; }
   };
 
-  typedef HashMap<int,
-                  AtomicString,
-                  DefaultHash<int>::Hash,
-                  UScriptCodeHashTraits>
+  typedef HashMap<int, AtomicString, DefaultHash<int>, UScriptCodeHashTraits>
       ScriptFontFamilyMap;
 
   void SetGenericFontFamilyMap(ScriptFontFamilyMap&,
diff --git a/third_party/blink/renderer/platform/fonts/shaping/shape_cache.h b/third_party/blink/renderer/platform/fonts/shaping/shape_cache.h
index c1a1efb..c7ab1fd 100644
--- a/third_party/blink/renderer/platform/fonts/shaping/shape_cache.h
+++ b/third_party/blink/renderer/platform/fonts/shaping/shape_cache.h
@@ -215,7 +215,7 @@
       SmallStringMap;
   typedef HashMap<uint32_t,
                   ShapeCacheEntry,
-                  DefaultHash<uint32_t>::Hash,
+                  DefaultHash<uint32_t>,
                   WTF::UnsignedWithZeroKeyHashTraits<uint32_t>>
       SingleCharMap;
 
diff --git a/third_party/blink/renderer/platform/geometry/geometry_hash_traits.h b/third_party/blink/renderer/platform/geometry/geometry_hash_traits.h
index 84e73815..242b462 100644
--- a/third_party/blink/renderer/platform/geometry/geometry_hash_traits.h
+++ b/third_party/blink/renderer/platform/geometry/geometry_hash_traits.h
@@ -14,19 +14,15 @@
 template <>
 struct DefaultHash<gfx::SizeF> {
   STATIC_ONLY(DefaultHash);
-  struct Hash {
-    STATIC_ONLY(Hash);
-    typedef typename IntTypes<sizeof(float)>::UnsignedType Bits;
-    static unsigned GetHash(const gfx::SizeF& key) {
-      return HashInts(DefaultHash<float>::Hash::GetHash(key.width()),
-                      DefaultHash<float>::Hash::GetHash(key.height()));
-    }
-    static bool Equal(const gfx::SizeF& a, const gfx::SizeF& b) {
-      return DefaultHash<float>::Hash::Equal(a.width(), b.width()) &&
-             DefaultHash<float>::Hash::Equal(a.height(), b.height());
-    }
-    static const bool safe_to_compare_to_empty_or_deleted = true;
-  };
+  static unsigned GetHash(const gfx::SizeF& key) {
+    return HashInts(DefaultHash<float>::GetHash(key.width()),
+                    DefaultHash<float>::GetHash(key.height()));
+  }
+  static bool Equal(const gfx::SizeF& a, const gfx::SizeF& b) {
+    return DefaultHash<float>::Equal(a.width(), b.width()) &&
+           DefaultHash<float>::Equal(a.height(), b.height());
+  }
+  static const bool safe_to_compare_to_empty_or_deleted = true;
 };
 
 template <>
@@ -52,15 +48,12 @@
 template <>
 struct DefaultHash<SkIRect> {
   STATIC_ONLY(DefaultHash);
-  struct Hash {
-    STATIC_ONLY(Hash);
-    static unsigned GetHash(const SkIRect& key) {
-      return HashInts(HashInts(key.x(), key.y()),
-                      HashInts(key.right(), key.bottom()));
-    }
-    static bool Equal(const SkIRect& a, const SkIRect& b) { return a == b; }
-    static const bool safe_to_compare_to_empty_or_deleted = true;
-  };
+  static unsigned GetHash(const SkIRect& key) {
+    return HashInts(HashInts(key.x(), key.y()),
+                    HashInts(key.right(), key.bottom()));
+  }
+  static bool Equal(const SkIRect& a, const SkIRect& b) { return a == b; }
+  static const bool safe_to_compare_to_empty_or_deleted = true;
 };
 
 template <>
diff --git a/third_party/blink/renderer/platform/graphics/color.h b/third_party/blink/renderer/platform/graphics/color.h
index 460fbfc0..59a2f84 100644
--- a/third_party/blink/renderer/platform/graphics/color.h
+++ b/third_party/blink/renderer/platform/graphics/color.h
@@ -318,14 +318,11 @@
 template <>
 struct DefaultHash<blink::Color> {
   STATIC_ONLY(DefaultHash);
-  struct Hash {
-    STATIC_ONLY(Hash);
-    static unsigned GetHash(const blink::Color& key) { return key.GetHash(); }
-    static bool Equal(const blink::Color& a, const blink::Color& b) {
-      return a == b;
-    }
-    static const bool safe_to_compare_to_empty_or_deleted = true;
-  };
+  static unsigned GetHash(const blink::Color& key) { return key.GetHash(); }
+  static bool Equal(const blink::Color& a, const blink::Color& b) {
+    return a == b;
+  }
+  static const bool safe_to_compare_to_empty_or_deleted = true;
 };
 }  // namespace WTF
 
diff --git a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h
index 6e50da99..0388ef7 100644
--- a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h
+++ b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h
@@ -50,7 +50,7 @@
   gpu::webgpu::WebGPUInterface* WebGPUInterface() override {
     return webgpu_.get();
   }
-  bool BindToCurrentThread() override { return false; }
+  bool BindToCurrentSequence() override { return false; }
   const gpu::Capabilities& GetCapabilities() const override {
     return capabilities_;
   }
diff --git a/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.cc b/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.cc
index 05ddd2e..d9e3f9a3 100644
--- a/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.cc
+++ b/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.cc
@@ -140,7 +140,7 @@
             CrossThreadUnretained(&waitable_event)));
     waitable_event.Wait();
     if (context_provider_wrapper_ &&
-        !context_provider_wrapper_->ContextProvider()->BindToCurrentThread())
+        !context_provider_wrapper_->ContextProvider()->BindToCurrentSequence())
       context_provider_wrapper_ = nullptr;
   }
 }
diff --git a/third_party/blink/renderer/platform/graphics/image_decoding_store.h b/third_party/blink/renderer/platform/graphics/image_decoding_store.h
index 17654ae..5ddf426 100644
--- a/third_party/blink/renderer/platform/graphics/image_decoding_store.h
+++ b/third_party/blink/renderer/platform/graphics/image_decoding_store.h
@@ -175,25 +175,21 @@
 template <>
 struct DefaultHash<blink::DecoderCacheKey> {
   STATIC_ONLY(DefaultHash);
-  struct Hash {
-    STATIC_ONLY(Hash);
-    static unsigned GetHash(const blink::DecoderCacheKey& p) {
-      auto first =
-          HashInts(DefaultHash<blink::ImageFrameGenerator*>::Hash::GetHash(
-                       const_cast<blink::ImageFrameGenerator*>(p.gen_)),
-                   DefaultHash<SkISize>::Hash::GetHash(p.size_));
-      auto second = HashInts(DefaultHash<uint8_t>::Hash::GetHash(
-                                 static_cast<uint8_t>(p.alpha_option_)),
-                             p.client_id_);
-      return HashInts(first, second);
-    }
-    static bool Equal(const blink::DecoderCacheKey& a,
-                      const blink::DecoderCacheKey& b) {
-      return a.gen_ == b.gen_ && a.size_ == b.size_ &&
-             a.alpha_option_ == b.alpha_option_ && a.client_id_ == b.client_id_;
-    }
-    static const bool safe_to_compare_to_empty_or_deleted = true;
-  };
+  static unsigned GetHash(const blink::DecoderCacheKey& p) {
+    auto first = HashInts(DefaultHash<blink::ImageFrameGenerator*>::GetHash(
+                              const_cast<blink::ImageFrameGenerator*>(p.gen_)),
+                          DefaultHash<SkISize>::GetHash(p.size_));
+    auto second = HashInts(
+        DefaultHash<uint8_t>::GetHash(static_cast<uint8_t>(p.alpha_option_)),
+        p.client_id_);
+    return HashInts(first, second);
+  }
+  static bool Equal(const blink::DecoderCacheKey& a,
+                    const blink::DecoderCacheKey& b) {
+    return a.gen_ == b.gen_ && a.size_ == b.size_ &&
+           a.alpha_option_ == b.alpha_option_ && a.client_id_ == b.client_id_;
+  }
+  static const bool safe_to_compare_to_empty_or_deleted = true;
 };
 
 template <>
diff --git a/third_party/blink/renderer/platform/graphics/memory_managed_paint_canvas.h b/third_party/blink/renderer/platform/graphics/memory_managed_paint_canvas.h
index 44f341b125..9da3fa2 100644
--- a/third_party/blink/renderer/platform/graphics/memory_managed_paint_canvas.h
+++ b/third_party/blink/renderer/platform/graphics/memory_managed_paint_canvas.h
@@ -52,7 +52,7 @@
   void UpdateMemoryUsage(const cc::PaintImage& image);
 
   HashSet<cc::PaintImage::ContentId,
-          DefaultHash<cc::PaintImage::ContentId>::Hash,
+          DefaultHash<cc::PaintImage::ContentId>,
           WTF::UnsignedWithZeroKeyHashTraits<cc::PaintImage::ContentId>>
       cached_image_ids_;
 
diff --git a/third_party/blink/renderer/platform/graphics/paint/display_item.h b/third_party/blink/renderer/platform/graphics/paint/display_item.h
index 2fd5651..04faca3 100644
--- a/third_party/blink/renderer/platform/graphics/paint/display_item.h
+++ b/third_party/blink/renderer/platform/graphics/paint/display_item.h
@@ -383,19 +383,16 @@
 
 template <>
 struct DefaultHash<blink::DisplayItem::Id::HashKey> {
-  struct Hash {
-    STATIC_ONLY(Hash);
-    using Key = blink::DisplayItem::Id::HashKey;
-    static unsigned GetHash(const Key& id) {
-      unsigned hash =
-          IntHash<blink::DisplayItemClientId>::GetHash(id.client_id);
-      WTF::AddIntToHash(hash, id.type);
-      WTF::AddIntToHash(hash, id.fragment);
-      return hash;
-    }
-    static bool Equal(const Key& a, const Key& b) { return a == b; }
-    static const bool safe_to_compare_to_empty_or_deleted = false;
-  };
+  STATIC_ONLY(DefaultHash);
+  using Key = blink::DisplayItem::Id::HashKey;
+  static unsigned GetHash(const Key& id) {
+    unsigned hash = IntHash<blink::DisplayItemClientId>::GetHash(id.client_id);
+    WTF::AddIntToHash(hash, id.type);
+    WTF::AddIntToHash(hash, id.fragment);
+    return hash;
+  }
+  static bool Equal(const Key& a, const Key& b) { return a == b; }
+  static const bool safe_to_compare_to_empty_or_deleted = false;
 };
 
 }  // namespace WTF
diff --git a/third_party/blink/renderer/platform/graphics/skia/sk_image_info_hash.h b/third_party/blink/renderer/platform/graphics/skia/sk_image_info_hash.h
index d3cad23..ed8afb9 100644
--- a/third_party/blink/renderer/platform/graphics/skia/sk_image_info_hash.h
+++ b/third_party/blink/renderer/platform/graphics/skia/sk_image_info_hash.h
@@ -14,21 +14,18 @@
 template <>
 struct DefaultHash<SkImageInfo> {
   STATIC_ONLY(DefaultHash);
-  struct Hash {
-    STATIC_ONLY(Hash);
-    static unsigned GetHash(const SkImageInfo& key) {
-      unsigned result = HashInts(key.width(), key.height());
-      result = HashInts(result, key.colorType());
-      result = HashInts(result, key.alphaType());
-      if (auto* cs = key.colorSpace())
-        result = HashInts(result, static_cast<uint32_t>(cs->hash()));
-      return result;
-    }
-    static bool Equal(const SkImageInfo& a, const SkImageInfo& b) {
-      return a == b;
-    }
-    static const bool safe_to_compare_to_empty_or_deleted = true;
-  };
+  static unsigned GetHash(const SkImageInfo& key) {
+    unsigned result = HashInts(key.width(), key.height());
+    result = HashInts(result, key.colorType());
+    result = HashInts(result, key.alphaType());
+    if (auto* cs = key.colorSpace())
+      result = HashInts(result, static_cast<uint32_t>(cs->hash()));
+    return result;
+  }
+  static bool Equal(const SkImageInfo& a, const SkImageInfo& b) {
+    return a == b;
+  }
+  static const bool safe_to_compare_to_empty_or_deleted = true;
 };
 
 template <>
diff --git a/third_party/blink/renderer/platform/graphics/skia/sk_size_hash.h b/third_party/blink/renderer/platform/graphics/skia/sk_size_hash.h
index 142b95f..4c4e01a 100644
--- a/third_party/blink/renderer/platform/graphics/skia/sk_size_hash.h
+++ b/third_party/blink/renderer/platform/graphics/skia/sk_size_hash.h
@@ -34,14 +34,11 @@
 template <>
 struct DefaultHash<SkSize> {
   STATIC_ONLY(DefaultHash);
-  struct Hash {
-    STATIC_ONLY(Hash);
-    static unsigned GetHash(const SkSize& key) {
-      return HashInts(key.width(), key.height());
-    }
-    static bool Equal(const SkSize& a, const SkSize& b) { return a == b; }
-    static const bool safe_to_compare_to_empty_or_deleted = true;
-  };
+  static unsigned GetHash(const SkSize& key) {
+    return HashInts(key.width(), key.height());
+  }
+  static bool Equal(const SkSize& a, const SkSize& b) { return a == b; }
+  static const bool safe_to_compare_to_empty_or_deleted = true;
 };
 
 template <>
@@ -60,14 +57,11 @@
 template <>
 struct DefaultHash<SkISize> {
   STATIC_ONLY(DefaultHash);
-  struct Hash {
-    STATIC_ONLY(Hash);
-    static unsigned GetHash(const SkISize& key) {
-      return HashInts(key.width(), key.height());
-    }
-    static bool Equal(const SkISize& a, const SkISize& b) { return a == b; }
-    static const bool safe_to_compare_to_empty_or_deleted = true;
-  };
+  static unsigned GetHash(const SkISize& key) {
+    return HashInts(key.width(), key.height());
+  }
+  static bool Equal(const SkISize& a, const SkISize& b) { return a == b; }
+  static const bool safe_to_compare_to_empty_or_deleted = true;
 };
 
 template <>
diff --git a/third_party/blink/renderer/platform/graphics/test/fake_web_graphics_context_3d_provider.h b/third_party/blink/renderer/platform/graphics/test/fake_web_graphics_context_3d_provider.h
index d7eec2f3..f4733c5d 100644
--- a/third_party/blink/renderer/platform/graphics/test/fake_web_graphics_context_3d_provider.h
+++ b/third_party/blink/renderer/platform/graphics/test/fake_web_graphics_context_3d_provider.h
@@ -87,7 +87,7 @@
     return webgpu_interface_.get();
   }
 
-  bool BindToCurrentThread() override { return false; }
+  bool BindToCurrentSequence() override { return false; }
   void SetLostContextCallback(base::RepeatingClosure) override {}
   void SetErrorMessageCallback(
       base::RepeatingCallback<void(const char*, int32_t id)>) override {}
diff --git a/third_party/blink/renderer/platform/graphics/test/gpu_test_utils.cc b/third_party/blink/renderer/platform/graphics/test/gpu_test_utils.cc
index 25e1b9b..bba5640 100644
--- a/third_party/blink/renderer/platform/graphics/test/gpu_test_utils.cc
+++ b/third_party/blink/renderer/platform/graphics/test/gpu_test_utils.cc
@@ -34,7 +34,7 @@
     context_provider->SetCapabilities(gl->test_capabilities());
     return context_provider;
   };
-  test_context_provider->BindToCurrentThread();
+  test_context_provider->BindToCurrentSequence();
   viz::TestGLES2Interface* gl = test_context_provider->TestContextGL();
   GrDirectContext* context = test_context_provider->GrContext();
   SharedGpuContext::SetContextProviderFactoryForTesting(WTF::BindRepeating(
diff --git a/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc b/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc
index 6101a6d..5ebd1f1 100644
--- a/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc
+++ b/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc
@@ -508,7 +508,7 @@
   }
 
   context_provider_ = std::move(context_provider);
-  if (context_provider_->BindToCurrentThread() !=
+  if (context_provider_->BindToCurrentSequence() !=
       gpu::ContextResult::kSuccess) {
     return false;
   }
diff --git a/third_party/blink/renderer/platform/graphics/video_frame_submitter_test.cc b/third_party/blink/renderer/platform/graphics/video_frame_submitter_test.cc
index 8b35473..b522ad3a 100644
--- a/third_party/blink/renderer/platform/graphics/video_frame_submitter_test.cc
+++ b/third_party/blink/renderer/platform/graphics/video_frame_submitter_test.cc
@@ -162,7 +162,7 @@
         begin_frame_source_(new viz::FakeExternalBeginFrameSource(0.f, false)),
         video_frame_provider_(new StrictMock<MockVideoFrameProvider>()),
         context_provider_(viz::TestContextProvider::Create()) {
-    context_provider_->BindToCurrentThread();
+    context_provider_->BindToCurrentSequence();
     MakeSubmitter();
     task_environment_.RunUntilIdle();
   }
diff --git a/third_party/blink/renderer/platform/heap/collection_support/heap_hash_counted_set.h b/third_party/blink/renderer/platform/heap/collection_support/heap_hash_counted_set.h
index 55252441..e5c6ba5 100644
--- a/third_party/blink/renderer/platform/heap/collection_support/heap_hash_counted_set.h
+++ b/third_party/blink/renderer/platform/heap/collection_support/heap_hash_counted_set.h
@@ -13,7 +13,7 @@
 namespace blink {
 
 template <typename Value,
-          typename HashFunctions = typename DefaultHash<Value>::Hash,
+          typename HashFunctions = DefaultHash<Value>,
           typename Traits = HashTraits<Value>>
 class HeapHashCountedSet final
     : public GarbageCollected<HeapHashCountedSet<Value, HashFunctions, Traits>>,
diff --git a/third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h b/third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h
index f194569..d5cd825 100644
--- a/third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h
+++ b/third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h
@@ -15,7 +15,7 @@
 
 template <typename KeyArg,
           typename MappedArg,
-          typename HashArg = typename DefaultHash<KeyArg>::Hash,
+          typename HashArg = DefaultHash<KeyArg>,
           typename KeyTraitsArg = HashTraits<KeyArg>,
           typename MappedTraitsArg = HashTraits<MappedArg>>
 class HeapHashMap final : public GarbageCollected<HeapHashMap<KeyArg,
diff --git a/third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h b/third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h
index f7369889..ab2fdf4 100644
--- a/third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h
+++ b/third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h
@@ -13,7 +13,7 @@
 namespace blink {
 
 template <typename ValueArg,
-          typename HashArg = typename DefaultHash<ValueArg>::Hash,
+          typename HashArg = DefaultHash<ValueArg>,
           typename TraitsArg = HashTraits<ValueArg>>
 class HeapHashSet final
     : public GarbageCollected<HeapHashSet<ValueArg, HashArg, TraitsArg>>,
diff --git a/third_party/blink/renderer/platform/heap/collection_support/heap_linked_hash_set.h b/third_party/blink/renderer/platform/heap/collection_support/heap_linked_hash_set.h
index f2f57a4..dcf8e95a 100644
--- a/third_party/blink/renderer/platform/heap/collection_support/heap_linked_hash_set.h
+++ b/third_party/blink/renderer/platform/heap/collection_support/heap_linked_hash_set.h
@@ -17,7 +17,7 @@
 
 template <typename ValueArg,
           typename TraitsArg = HashTraits<ValueArg>,
-          typename HashArg = typename DefaultHash<ValueArg>::Hash>
+          typename HashArg = DefaultHash<ValueArg>>
 class HeapLinkedHashSet final
     : public GarbageCollected<HeapLinkedHashSet<ValueArg, TraitsArg, HashArg>>,
       public LinkedHashSet<ValueArg, TraitsArg, HashArg, HeapAllocator> {
diff --git a/third_party/blink/renderer/platform/heap/cross_thread_persistent.h b/third_party/blink/renderer/platform/heap/cross_thread_persistent.h
index 70fe339..5f106445 100644
--- a/third_party/blink/renderer/platform/heap/cross_thread_persistent.h
+++ b/third_party/blink/renderer/platform/heap/cross_thread_persistent.h
@@ -71,16 +71,11 @@
     : BasePersistentHashTraits<T, blink::CrossThreadWeakPersistent<T>> {};
 
 template <typename T>
-struct DefaultHash<blink::CrossThreadPersistent<T>> {
-  STATIC_ONLY(DefaultHash);
-  using Hash = PersistentHashBase<T>;
-};
+struct DefaultHash<blink::CrossThreadPersistent<T>> : PersistentHashBase<T> {};
 
 template <typename T>
-struct DefaultHash<blink::CrossThreadWeakPersistent<T>> {
-  STATIC_ONLY(DefaultHash);
-  using Hash = PersistentHashBase<T>;
-};
+struct DefaultHash<blink::CrossThreadWeakPersistent<T>>
+    : PersistentHashBase<T> {};
 
 template <typename T>
 struct CrossThreadCopier<blink::CrossThreadPersistent<T>>
diff --git a/third_party/blink/renderer/platform/heap/member.h b/third_party/blink/renderer/platform/heap/member.h
index 1d0b7b53..40763cb 100644
--- a/third_party/blink/renderer/platform/heap/member.h
+++ b/third_party/blink/renderer/platform/heap/member.h
@@ -92,22 +92,13 @@
 };
 
 template <typename T>
-struct DefaultHash<blink::Member<T>> {
-  STATIC_ONLY(DefaultHash);
-  using Hash = MemberHash<T>;
-};
+struct DefaultHash<blink::Member<T>> : MemberHash<T> {};
 
 template <typename T>
-struct DefaultHash<blink::WeakMember<T>> {
-  STATIC_ONLY(DefaultHash);
-  using Hash = MemberHash<T>;
-};
+struct DefaultHash<blink::WeakMember<T>> : MemberHash<T> {};
 
 template <typename T>
-struct DefaultHash<blink::UntracedMember<T>> {
-  STATIC_ONLY(DefaultHash);
-  using Hash = MemberHash<T>;
-};
+struct DefaultHash<blink::UntracedMember<T>> : MemberHash<T> {};
 
 template <typename T>
 struct IsTraceable<blink::Member<T>> {
diff --git a/third_party/blink/renderer/platform/heap/persistent.h b/third_party/blink/renderer/platform/heap/persistent.h
index a6d01aa..3718057 100644
--- a/third_party/blink/renderer/platform/heap/persistent.h
+++ b/third_party/blink/renderer/platform/heap/persistent.h
@@ -214,28 +214,18 @@
 };
 
 template <typename T>
-struct DefaultHash<blink::Persistent<T>> {
-  STATIC_ONLY(DefaultHash);
-  using Hash = PersistentHashBase<T>;
-};
+struct DefaultHash<blink::Persistent<T>> : PersistentHashBase<T> {};
 
 template <typename T>
-struct DefaultHash<blink::WeakPersistent<T>> {
-  STATIC_ONLY(DefaultHash);
-  using Hash = PersistentHashBase<T>;
-};
+struct DefaultHash<blink::WeakPersistent<T>> : PersistentHashBase<T> {};
 
 // template <typename T>
-// struct DefaultHash<blink::CrossThreadPersistent<T>> {
-//   STATIC_ONLY(DefaultHash);
-//   using Hash = PersistentHashBase<T>;
-// };
+// struct DefaultHash<blink::CrossThreadPersistent<T>> : PersistentHashBase<T>
+// {};
 
 // template <typename T>
-// struct DefaultHash<blink::CrossThreadWeakPersistent<T>> {
-//   STATIC_ONLY(DefaultHash);
-//   using Hash = PersistentHashBase<T>;
-// };
+// struct DefaultHash<blink::CrossThreadWeakPersistent<T>> :
+// PersistentHashBase<T> {};
 
 // template <typename T>
 // struct CrossThreadCopier<blink::CrossThreadPersistent<T>>
diff --git a/third_party/blink/renderer/platform/heap/test/heap_test.cc b/third_party/blink/renderer/platform/heap/test/heap_test.cc
index 9e9a185..ea4cb725 100644
--- a/third_party/blink/renderer/platform/heap/test/heap_test.cc
+++ b/third_party/blink/renderer/platform/heap/test/heap_test.cc
@@ -498,9 +498,7 @@
 template <typename T>
 struct DefaultHash;
 template <>
-struct DefaultHash<blink::ThreadMarker> {
-  typedef blink::ThreadMarkerHash Hash;
-};
+struct DefaultHash<blink::ThreadMarker> : blink::ThreadMarkerHash {};
 
 // ThreadMarkerHash is the default hash for ThreadMarker
 template <>
@@ -634,10 +632,9 @@
   IntWrapper::destructor_calls_ = 0;
   size_t initial_object_payload_size = GetOverallObjectSize();
   {
-    typedef HeapHashMap<Member<IntWrapper>, Member<IntWrapper>,
-                        DefaultHash<Member<IntWrapper>>::Hash,
-                        HashTraits<Member<IntWrapper>>,
-                        HashTraits<Member<IntWrapper>>>
+    typedef HeapHashMap<
+        Member<IntWrapper>, Member<IntWrapper>, DefaultHash<Member<IntWrapper>>,
+        HashTraits<Member<IntWrapper>>, HashTraits<Member<IntWrapper>>>
         HeapObjectIdentityMap;
 
     Persistent<HeapObjectIdentityMap> map =
@@ -1736,7 +1733,7 @@
       RefMap;
 
   typedef HeapHashMap<WeakMember<IntWrapper>, ThingWithDestructor,
-                      DefaultHash<WeakMember<IntWrapper>>::Hash,
+                      DefaultHash<WeakMember<IntWrapper>>,
                       HashTraits<WeakMember<IntWrapper>>>
       Map;
 
@@ -3113,7 +3110,7 @@
   DISALLOW_NEW();
 
  public:
-  struct Hash final {
+  struct Hash {
     STATIC_ONLY(Hash);
 
    public:
@@ -3161,9 +3158,8 @@
 namespace WTF {
 
 template <>
-struct DefaultHash<blink::KeyWithCopyingMoveConstructor> {
-  using Hash = blink::KeyWithCopyingMoveConstructor::Hash;
-};
+struct DefaultHash<blink::KeyWithCopyingMoveConstructor>
+    : blink::KeyWithCopyingMoveConstructor::Hash {};
 
 template <>
 struct HashTraits<blink::KeyWithCopyingMoveConstructor>
diff --git a/third_party/blink/renderer/platform/image-decoders/exif_reader.cc b/third_party/blink/renderer/platform/image-decoders/exif_reader.cc
new file mode 100644
index 0000000..289d772c
--- /dev/null
+++ b/third_party/blink/renderer/platform/image-decoders/exif_reader.cc
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Portions are Copyright (C) 2001-6 mozilla.org
+ *
+ * Other contributors:
+ *   Stuart Parmenter <stuart@mozilla.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Alternatively, the contents of this file may be used under the terms
+ * of either the Mozilla Public License Version 1.1, found at
+ * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
+ * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
+ * (the "GPL"), in which case the provisions of the MPL or the GPL are
+ * applicable instead of those above.  If you wish to allow use of your
+ * version of this file only under the terms of one of those two
+ * licenses (the MPL or the GPL) and not to allow others to use your
+ * version of this file under the LGPL, indicate your decision by
+ * deletingthe provisions above and replace them with the notice and
+ * other provisions required by the MPL or the GPL, as the case may be.
+ * If you do not delete the provisions above, a recipient may use your
+ * version of this file under any of the LGPL, the MPL or the GPL.
+ */
+
+#include "third_party/blink/renderer/platform/image-decoders/exif_reader.h"
+
+namespace blink {
+
+namespace {
+
+constexpr unsigned kExifHeaderSize = 8;
+
+unsigned ReadUint16(const uint8_t* data, bool is_big_endian) {
+  if (is_big_endian)
+    return (data[0] << 8) | data[1];
+  return (data[1] << 8) | data[0];
+}
+
+unsigned ReadUint32(const uint8_t* data, bool is_big_endian) {
+  if (is_big_endian)
+    return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
+  return (data[3] << 24) | (data[2] << 16) | (data[1] << 8) | data[0];
+}
+
+float ReadUnsignedRational(const uint8_t* data, bool is_big_endian) {
+  unsigned nom = ReadUint32(data, is_big_endian);
+  unsigned denom = ReadUint32(data + 4, is_big_endian);
+  if (!denom)
+    return 0;
+  return float(nom) / float(denom);
+}
+
+bool ReadExifHeader(base::span<const uint8_t> data, bool& is_big_endian) {
+  // A TIFF file starts with 'I', 'I' (Intel / little endian byte order) or
+  // 'M', 'M' (Motorola / big endian byte order), followed by (uint16_t)42,
+  // followed by an uint32_t with the offset to the initial (0th) IFD tag
+  // block, relative to the TIFF file start.
+  //
+  // Header in summary:
+  // <byte-order tag> (2 bytes), <magic> (2 bytes), <0th IFD offset> (4 bytes)
+  if (data.size() < kExifHeaderSize)
+    return false;
+  const uint8_t byte_order = data[0];
+  if (byte_order != data[1])
+    return false;
+  if (byte_order != 'I' && byte_order != 'M')
+    return false;
+  is_big_endian = byte_order == 'M';
+  if (ReadUint16(data.data() + 2, is_big_endian) != 42)
+    return false;
+  return true;
+}
+
+void ReadExifDirectory(const uint8_t* dir_start,
+                       const uint8_t* data_start,
+                       const uint8_t* data_end,
+                       bool is_big_endian,
+                       DecodedImageMetaData& metadata,
+                       bool is_root = true) {
+  const unsigned kUnsignedShortType = 3;
+  const unsigned kUnsignedLongType = 4;
+  const unsigned kUnsignedRationalType = 5;
+
+  enum ExifTags {
+    kOrientationTag = 0x112,
+    kResolutionXTag = 0x11a,
+    kResolutionYTag = 0x11b,
+    kResolutionUnitTag = 0x128,
+    kPixelXDimensionTag = 0xa002,
+    kPixelYDimensionTag = 0xa003,
+    kExifOffsetTag = 0x8769
+  };
+
+  if (data_end - dir_start < 2)
+    return;
+
+  const unsigned max_offset =
+      base::checked_cast<unsigned>(data_end - data_start);
+  unsigned tag_count = ReadUint16(dir_start, is_big_endian);
+  const uint8_t* ifd =
+      dir_start + 2;  // Skip over the uint16 that was just read.
+
+  // A TIFF image file directory (IFD) consists of a uint16_t describing the
+  // number of IFD entries, followed by that many entries. Every IFD entry is 2
+  // bytes of tag, 2 bytes of contents datatype, 4 bytes of number-of-elements,
+  // and 4 bytes of either offset to the tag data, or if the data is small
+  // enough, the inlined data itself.
+  const int kIfdEntrySize = 12;
+  for (unsigned i = 0; i < tag_count && data_end - ifd >= kIfdEntrySize;
+       ++i, ifd += kIfdEntrySize) {
+    unsigned tag = ReadUint16(ifd, is_big_endian);
+    unsigned type = ReadUint16(ifd + 2, is_big_endian);
+    unsigned count = ReadUint32(ifd + 4, is_big_endian);
+    const uint8_t* value_ptr = ifd + 8;
+
+    // EXIF stores the value with an offset if it's bigger than 4 bytes, e.g.
+    // for rational values.
+    if (type == kUnsignedRationalType) {
+      unsigned offset = ReadUint32(value_ptr, is_big_endian);
+      if (offset > max_offset)
+        continue;
+      value_ptr = data_start + offset;
+      // Make sure offset points to a valid location.
+      if (value_ptr > data_end - 16)
+        continue;
+    }
+
+    switch (tag) {
+      case ExifTags::kOrientationTag:
+        if (type == kUnsignedShortType && count == 1) {
+          metadata.orientation = ImageOrientation::FromEXIFValue(
+              ReadUint16(value_ptr, is_big_endian));
+        }
+        break;
+
+      case ExifTags::kResolutionUnitTag:
+        if (type == kUnsignedShortType && count == 1)
+          metadata.resolution_unit = ReadUint16(value_ptr, is_big_endian);
+        break;
+
+      case ExifTags::kResolutionXTag:
+        if (type == kUnsignedRationalType && count == 1) {
+          metadata.resolution.set_width(
+              ReadUnsignedRational(value_ptr, is_big_endian));
+        }
+        break;
+
+      case ExifTags::kResolutionYTag:
+        if (type == kUnsignedRationalType && count == 1) {
+          metadata.resolution.set_height(
+              ReadUnsignedRational(value_ptr, is_big_endian));
+        }
+        break;
+
+      case ExifTags::kPixelXDimensionTag:
+        if (count != 1)
+          break;
+        switch (type) {
+          case kUnsignedShortType:
+            metadata.size.set_width(ReadUint16(value_ptr, is_big_endian));
+            break;
+          case kUnsignedLongType:
+            metadata.size.set_width(ReadUint32(value_ptr, is_big_endian));
+            break;
+        }
+        break;
+
+      case ExifTags::kPixelYDimensionTag:
+        if (count != 1)
+          break;
+        switch (type) {
+          case kUnsignedShortType:
+            metadata.size.set_height(ReadUint16(value_ptr, is_big_endian));
+            break;
+          case kUnsignedLongType:
+            metadata.size.set_height(ReadUint32(value_ptr, is_big_endian));
+            break;
+        }
+        break;
+
+      case ExifTags::kExifOffsetTag:
+        if (type == kUnsignedLongType && count == 1 && is_root) {
+          unsigned offset = ReadUint32(value_ptr, is_big_endian);
+          if (offset > max_offset)
+            break;
+          const uint8_t* subdir = data_start + offset;
+          ReadExifDirectory(subdir, data_start, data_end, is_big_endian,
+                            metadata, false);
+        }
+        break;
+    }
+  }
+}
+
+}  // namespace
+
+bool ReadExif(base::span<const uint8_t> data, DecodedImageMetaData& metadata) {
+  bool is_big_endian;
+  if (!ReadExifHeader(data, is_big_endian))
+    return false;
+  const unsigned ifd_offset = ReadUint32(data.data() + 4, is_big_endian);
+  if (ifd_offset < kExifHeaderSize || ifd_offset >= data.size())
+    return false;
+
+  const uint8_t* data_end = data.data() + data.size();
+  const uint8_t* data_start = data.data();
+  const uint8_t* ifd0 = data_start + ifd_offset;
+  ReadExifDirectory(ifd0, data_start, data_end, is_big_endian, metadata);
+  return true;
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/platform/image-decoders/exif_reader.h b/third_party/blink/renderer/platform/image-decoders/exif_reader.h
new file mode 100644
index 0000000..8c828dab
--- /dev/null
+++ b/third_party/blink/renderer/platform/image-decoders/exif_reader.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Portions are Copyright (C) 2001-6 mozilla.org
+ *
+ * Other contributors:
+ *   Stuart Parmenter <stuart@mozilla.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Alternatively, the contents of this file may be used under the terms
+ * of either the Mozilla Public License Version 1.1, found at
+ * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
+ * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
+ * (the "GPL"), in which case the provisions of the MPL or the GPL are
+ * applicable instead of those above.  If you wish to allow use of your
+ * version of this file only under the terms of one of those two
+ * licenses (the MPL or the GPL) and not to allow others to use your
+ * version of this file under the LGPL, indicate your decision by
+ * deletingthe provisions above and replace them with the notice and
+ * other provisions required by the MPL or the GPL, as the case may be.
+ * If you do not delete the provisions above, a recipient may use your
+ * version of this file under any of the LGPL, the MPL or the GPL.
+ */
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_IMAGE_DECODERS_EXIF_READER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_IMAGE_DECODERS_EXIF_READER_H_
+
+#include "base/containers/span.h"
+#include "third_party/blink/renderer/platform/graphics/image_orientation.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/gfx/geometry/size_f.h"
+
+namespace blink {
+
+struct DecodedImageMetaData {
+  ImageOrientation orientation;
+  gfx::SizeF resolution;
+  gfx::Size size;
+  unsigned resolution_unit{0};
+};
+
+// Read EXIF data from |data|, populating |metadata| if the relevant tags are
+// found.
+// Returns false if an unrecoverable error (not EXIF data, no 0th IFD) is
+// encountered, otherwise true.
+bool ReadExif(base::span<const uint8_t> data, DecodedImageMetaData& metadata);
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_IMAGE_DECODERS_EXIF_READER_H_
diff --git a/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc b/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc
index 86f6bd5..30d8c75 100644
--- a/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc
+++ b/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc
@@ -44,11 +44,11 @@
 #include "base/numerics/checked_math.h"
 #include "build/build_config.h"
 #include "third_party/blink/renderer/platform/graphics/bitmap_image_metrics.h"
+#include "third_party/blink/renderer/platform/image-decoders/exif_reader.h"
 #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "third_party/skia/include/core/SkColorSpace.h"
 #include "ui/gfx/geometry/size_conversions.h"
-#include "ui/gfx/geometry/size_f.h"
 
 extern "C" {
 #include <stdio.h>  // jpeglib.h needs stdio FILE.
@@ -85,7 +85,6 @@
 
 constexpr int kExifMarker = JPEG_APP0 + 1;
 constexpr unsigned kExifAPP1SignatureSize = 6;
-constexpr unsigned kExifHeaderSize = 8;
 
 // JPEG only supports a denominator of 8.
 const unsigned g_scale_denominator = 8;
@@ -215,68 +214,6 @@
 void error_exit(j_common_ptr cinfo);
 void emit_message(j_common_ptr cinfo, int msg_level);
 
-static unsigned ReadUint16(const uint8_t* data, bool is_big_endian) {
-  if (is_big_endian)
-    return (data[0] << 8) | data[1];
-  return (data[1] << 8) | data[0];
-}
-
-static unsigned ReadUint32(const uint8_t* data, bool is_big_endian) {
-  if (is_big_endian)
-    return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
-  return (data[3] << 24) | (data[2] << 16) | (data[1] << 8) | data[0];
-}
-
-static float ReadUnsignedRational(const uint8_t* data, bool is_big_endian) {
-  unsigned nom = ReadUint32(data, is_big_endian);
-  unsigned denom = ReadUint32(data + 4, is_big_endian);
-  if (!denom)
-    return 0;
-  return float(nom) / float(denom);
-}
-
-static bool IsExifData(jpeg_saved_marker_ptr marker) {
-  // For EXIF data, the APP1 block is followed by 'E', 'x', 'i', 'f', '\0',
-  // then a fill byte, and then a TIFF file that contains the metadata.
-  if (marker->marker != kExifMarker)
-    return false;
-  if (marker->data_length < kExifAPP1SignatureSize)
-    return false;
-  const uint8_t kExifAPP1Signature[5] = {'E', 'x', 'i', 'f', '\0'};
-  if (memcmp(marker->data, kExifAPP1Signature, sizeof(kExifAPP1Signature)) != 0)
-    return false;
-  return true;
-}
-
-static bool ReadExifHeader(base::span<const uint8_t> data,
-                           bool& is_big_endian) {
-  // A TIFF file starts with 'I', 'I' (Intel / little endian byte order) or
-  // 'M', 'M' (Motorola / big endian byte order), followed by (uint16_t)42,
-  // followed by an uint32_t with the offset to the initial (0th) IFD tag
-  // block, relative to the TIFF file start.
-  //
-  // Header in summary:
-  // <byte-order tag> (2 bytes), <magic> (2 bytes), <0th IFD offset> (4 bytes)
-  if (data.size() < kExifHeaderSize)
-    return false;
-  const uint8_t byte_order = data[0];
-  if (byte_order != data[1])
-    return false;
-  if (byte_order != 'I' && byte_order != 'M')
-    return false;
-  is_big_endian = byte_order == 'M';
-  if (ReadUint16(data.data() + 2, is_big_endian) != 42)
-    return false;
-  return true;
-}
-
-struct DecodedImageMetaData {
-  ImageOrientation orientation;
-  gfx::SizeF resolution;
-  gfx::Size size;
-  unsigned resolution_unit { 0 };
-};
-
 static gfx::Size ExtractDensityCorrectedSize(
     const DecodedImageMetaData& metadata,
     const gfx::Size& physical_size) {
@@ -301,137 +238,16 @@
   return physical_size;
 }
 
-static void ReadExifDirectory(const uint8_t* dir_start,
-                              const uint8_t* data_start,
-                              const uint8_t* data_end,
-                              bool is_big_endian,
-                              DecodedImageMetaData& metadata,
-                              bool is_root = true) {
-  const unsigned kUnsignedShortType = 3;
-  const unsigned kUnsignedLongType = 4;
-  const unsigned kUnsignedRationalType = 5;
-
-  enum ExifTags {
-    kOrientationTag = 0x112,
-    kResolutionXTag = 0x11a,
-    kResolutionYTag = 0x11b,
-    kResolutionUnitTag = 0x128,
-    kPixelXDimensionTag = 0xa002,
-    kPixelYDimensionTag = 0xa003,
-    kExifOffsetTag = 0x8769
-  };
-
-  if (data_end - dir_start < 2)
-    return;
-
-  const unsigned max_offset =
-      base::checked_cast<unsigned>(data_end - data_start);
-  unsigned tag_count = ReadUint16(dir_start, is_big_endian);
-  const uint8_t* ifd =
-      dir_start + 2;  // Skip over the uint16 that was just read.
-
-  // A TIFF image file directory (IFD) consists of a uint16_t describing the
-  // number of IFD entries, followed by that many entries. Every IFD entry is 2
-  // bytes of tag, 2 bytes of contents datatype, 4 bytes of number-of-elements,
-  // and 4 bytes of either offset to the tag data, or if the data is small
-  // enough, the inlined data itself.
-  const int kIfdEntrySize = 12;
-  for (unsigned i = 0; i < tag_count && data_end - ifd >= kIfdEntrySize;
-        ++i, ifd += kIfdEntrySize) {
-    unsigned tag = ReadUint16(ifd, is_big_endian);
-    unsigned type = ReadUint16(ifd + 2, is_big_endian);
-    unsigned count = ReadUint32(ifd + 4, is_big_endian);
-    const uint8_t* value_ptr = ifd + 8;
-
-    // EXIF stores the value with an offset if it's bigger than 4 bytes, e.g. for rational values.
-    if (type == kUnsignedRationalType) {
-      unsigned offset = ReadUint32(value_ptr, is_big_endian);
-      if (offset > max_offset)
-        continue;
-      value_ptr = data_start + offset;
-      // Make sure offset points to a valid location.
-      if (value_ptr > data_end - 16)
-        continue;
-    }
-
-    switch (tag) {
-      case ExifTags::kOrientationTag:
-        if (type == kUnsignedShortType && count == 1)
-          metadata.orientation = ImageOrientation::FromEXIFValue(ReadUint16(value_ptr, is_big_endian));
-        break;
-
-      case ExifTags::kResolutionUnitTag:
-        if (type == kUnsignedShortType && count == 1)
-          metadata.resolution_unit = ReadUint16(value_ptr, is_big_endian);
-        break;
-
-      case ExifTags::kResolutionXTag:
-        if (type == kUnsignedRationalType && count == 1) {
-          metadata.resolution.set_width(
-              ReadUnsignedRational(value_ptr, is_big_endian));
-        }
-        break;
-
-      case ExifTags::kResolutionYTag:
-        if (type == kUnsignedRationalType && count == 1) {
-          metadata.resolution.set_height(
-              ReadUnsignedRational(value_ptr, is_big_endian));
-        }
-        break;
-
-      case ExifTags::kPixelXDimensionTag:
-        if (count != 1)
-          break;
-        switch (type) {
-          case kUnsignedShortType:
-            metadata.size.set_width(ReadUint16(value_ptr, is_big_endian));
-            break;
-          case kUnsignedLongType:
-            metadata.size.set_width(ReadUint32(value_ptr, is_big_endian));
-            break;
-        }
-        break;
-
-      case ExifTags::kPixelYDimensionTag:
-        if (count != 1)
-          break;
-        switch (type) {
-          case kUnsignedShortType:
-            metadata.size.set_height(ReadUint16(value_ptr, is_big_endian));
-            break;
-          case kUnsignedLongType:
-            metadata.size.set_height(ReadUint32(value_ptr, is_big_endian));
-            break;
-        }
-        break;
-
-      case ExifTags::kExifOffsetTag:
-        if (type == kUnsignedLongType && count == 1 && is_root) {
-          unsigned offset = ReadUint32(value_ptr, is_big_endian);
-          if (offset > max_offset)
-            break;
-          const uint8_t* subdir = data_start + offset;
-          ReadExifDirectory(subdir, data_start, data_end, is_big_endian,
-                            metadata, false);
-        }
-        break;
-    }
-  }
-}
-
-static bool ReadExif(base::span<const uint8_t> data,
-                     DecodedImageMetaData& metadata) {
-  bool is_big_endian;
-  if (!ReadExifHeader(data, is_big_endian))
+static bool IsExifData(jpeg_saved_marker_ptr marker) {
+  // For EXIF data, the APP1 block is followed by 'E', 'x', 'i', 'f', '\0',
+  // then a fill byte, and then a TIFF file that contains the metadata.
+  if (marker->marker != kExifMarker)
     return false;
-  const unsigned ifd_offset = ReadUint32(data.data() + 4, is_big_endian);
-  if (ifd_offset < kExifHeaderSize || ifd_offset >= data.size())
+  if (marker->data_length < kExifAPP1SignatureSize)
     return false;
-
-  const uint8_t* data_end = data.data() + data.size();
-  const uint8_t* data_start = data.data();
-  const uint8_t* ifd0 = data_start + ifd_offset;
-  ReadExifDirectory(ifd0, data_start, data_end, is_big_endian, metadata);
+  const uint8_t kExifAPP1Signature[5] = {'E', 'x', 'i', 'f', '\0'};
+  if (memcmp(marker->data, kExifAPP1Signature, sizeof(kExifAPP1Signature)) != 0)
+    return false;
   return true;
 }
 
diff --git a/third_party/blink/renderer/platform/loader/OWNERS b/third_party/blink/renderer/platform/loader/OWNERS
index 06f974c..ade1ebb 100644
--- a/third_party/blink/renderer/platform/loader/OWNERS
+++ b/third_party/blink/renderer/platform/loader/OWNERS
@@ -1,5 +1,4 @@
 hiroshige@chromium.org
 japhet@chromium.org
-mkwst@chromium.org
 toyoshim@chromium.org
 yoavweiss@chromium.org
diff --git a/third_party/blink/renderer/platform/loader/fetch/integrity_metadata.h b/third_party/blink/renderer/platform/loader/fetch/integrity_metadata.h
index 7619a8e3..9c3fae5 100644
--- a/third_party/blink/renderer/platform/loader/fetch/integrity_metadata.h
+++ b/third_party/blink/renderer/platform/loader/fetch/integrity_metadata.h
@@ -56,10 +56,8 @@
 namespace WTF {
 
 template <>
-struct DefaultHash<blink::IntegrityAlgorithm> {
-  STATIC_ONLY(DefaultHash);
-  typedef IntHash<blink::IntegrityAlgorithm> Hash;
-};
+struct DefaultHash<blink::IntegrityAlgorithm>
+    : IntHash<blink::IntegrityAlgorithm> {};
 
 template <>
 struct HashTraits<blink::IntegrityAlgorithm>
diff --git a/third_party/blink/renderer/platform/loader/fetch/preload_key.h b/third_party/blink/renderer/platform/loader/fetch/preload_key.h
index 7f1177f0..83d3216 100644
--- a/third_party/blink/renderer/platform/loader/fetch/preload_key.h
+++ b/third_party/blink/renderer/platform/loader/fetch/preload_key.h
@@ -54,9 +54,7 @@
 namespace WTF {
 
 template <>
-struct DefaultHash<blink::PreloadKey> {
-  using Hash = blink::PreloadKey::Hash;
-};
+struct DefaultHash<blink::PreloadKey> : blink::PreloadKey::Hash {};
 
 template <>
 struct HashTraits<blink::PreloadKey>
diff --git a/third_party/blink/renderer/platform/media/web_media_player_builder.cc b/third_party/blink/renderer/platform/media/web_media_player_builder.cc
index 9b3cd2e..7499445b 100644
--- a/third_party/blink/renderer/platform/media/web_media_player_builder.cc
+++ b/third_party/blink/renderer/platform/media/web_media_player_builder.cc
@@ -41,7 +41,7 @@
     media::MediaPlayerLoggingID player_id,
     DeferLoadCB defer_load_cb,
     scoped_refptr<media::SwitchableAudioRendererSink> audio_renderer_sink,
-    scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+    scoped_refptr<base::SequencedTaskRunner> media_task_runner,
     scoped_refptr<base::TaskRunner> worker_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner>
diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl.cc b/third_party/blink/renderer/platform/media/web_media_player_impl.cc
index 9961397..8287f504 100644
--- a/third_party/blink/renderer/platform/media/web_media_player_impl.cc
+++ b/third_party/blink/renderer/platform/media/web_media_player_impl.cc
@@ -25,6 +25,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/task/task_runner_util.h"
 #include "base/task/thread_pool.h"
@@ -400,7 +401,7 @@
     media::MediaPlayerLoggingID player_id,
     WebMediaPlayerBuilder::DeferLoadCB defer_load_cb,
     scoped_refptr<media::SwitchableAudioRendererSink> audio_renderer_sink,
-    scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+    scoped_refptr<base::SequencedTaskRunner> media_task_runner,
     scoped_refptr<base::TaskRunner> worker_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner>
diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl.h b/third_party/blink/renderer/platform/media/web_media_player_impl.h
index 31b94dd..86e80ef59 100644
--- a/third_party/blink/renderer/platform/media/web_media_player_impl.h
+++ b/third_party/blink/renderer/platform/media/web_media_player_impl.h
@@ -17,6 +17,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/threading/thread.h"
 #include "base/time/default_tick_clock.h"
 #include "base/time/time.h"
@@ -125,7 +126,7 @@
       media::MediaPlayerLoggingID player_id,
       WebMediaPlayerBuilder::DeferLoadCB defer_load_cb,
       scoped_refptr<media::SwitchableAudioRendererSink> audio_renderer_sink,
-      scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+      scoped_refptr<base::SequencedTaskRunner> media_task_runner,
       scoped_refptr<base::TaskRunner> worker_task_runner,
       scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
       scoped_refptr<base::SingleThreadTaskRunner>
@@ -689,7 +690,7 @@
   // Task runner for posting tasks on Chrome's main thread. Also used
   // for DCHECKs so methods calls won't execute in the wrong thread.
   const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
-  const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+  const scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
   const scoped_refptr<base::TaskRunner> worker_task_runner_;
 
   // This is the ID that is used within the internals of the media element
diff --git a/third_party/blink/renderer/platform/network/blink_schemeful_site.h b/third_party/blink/renderer/platform/network/blink_schemeful_site.h
index 765a14c..00f836c9 100644
--- a/third_party/blink/renderer/platform/network/blink_schemeful_site.h
+++ b/third_party/blink/renderer/platform/network/blink_schemeful_site.h
@@ -120,21 +120,19 @@
 
 template <>
 struct DefaultHash<blink::BlinkSchemefulSite> {
-  struct Hash {
-    STATIC_ONLY(Hash);
+  STATIC_ONLY(DefaultHash);
 
-    static unsigned GetHash(const blink::BlinkSchemefulSite& schemeful_site) {
-      return blink::SecurityOriginHash::GetHash(schemeful_site.site_as_origin_);
-    }
+  static unsigned GetHash(const blink::BlinkSchemefulSite& schemeful_site) {
+    return blink::SecurityOriginHash::GetHash(schemeful_site.site_as_origin_);
+  }
 
-    static bool Equal(const blink::BlinkSchemefulSite& a,
-                      const blink::BlinkSchemefulSite& b) {
-      return blink::SecurityOriginHash::Equal(a.site_as_origin_,
-                                              b.site_as_origin_);
-    }
+  static bool Equal(const blink::BlinkSchemefulSite& a,
+                    const blink::BlinkSchemefulSite& b) {
+    return blink::SecurityOriginHash::Equal(a.site_as_origin_,
+                                            b.site_as_origin_);
+  }
 
-    static const bool safe_to_compare_to_empty_or_deleted = false;
-  };
+  static const bool safe_to_compare_to_empty_or_deleted = false;
 };
 
 template <>
diff --git a/third_party/blink/renderer/platform/scheduler/BUILD.gn b/third_party/blink/renderer/platform/scheduler/BUILD.gn
index deceee0..966d1eb 100644
--- a/third_party/blink/renderer/platform/scheduler/BUILD.gn
+++ b/third_party/blink/renderer/platform/scheduler/BUILD.gn
@@ -120,6 +120,8 @@
     "public/cooperative_scheduling_manager.h",
     "public/dummy_schedulers.h",
     "public/event_loop.h",
+    "public/feature_and_js_location_blocking_bfcache.cc",
+    "public/feature_and_js_location_blocking_bfcache.h",
     "public/frame_or_worker_scheduler.h",
     "public/frame_scheduler.h",
     "public/frame_status.h",
diff --git a/third_party/blink/renderer/platform/scheduler/common/DEPS b/third_party/blink/renderer/platform/scheduler/common/DEPS
index 62e4350..c3bb9ff 100644
--- a/third_party/blink/renderer/platform/scheduler/common/DEPS
+++ b/third_party/blink/renderer/platform/scheduler/common/DEPS
@@ -1,4 +1,7 @@
 specific_include_rules = {
+ "back_forward_cache_disabling_feature_tracker_unittest.cc": [
+  "+third_party/blink/renderer/platform/bindings/source_location.h",
+ ],
  "frame_or_worker_scheduler.cc": [
   "+third_party/blink/renderer/platform/bindings/source_location.h",
  ],
diff --git a/third_party/blink/renderer/platform/scheduler/common/back_forward_cache_disabling_feature_tracker.cc b/third_party/blink/renderer/platform/scheduler/common/back_forward_cache_disabling_feature_tracker.cc
index 08b5c48d..bb099c5 100644
--- a/third_party/blink/renderer/platform/scheduler/common/back_forward_cache_disabling_feature_tracker.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/back_forward_cache_disabling_feature_tracker.cc
@@ -38,27 +38,49 @@
   back_forward_cache_disabling_feature_counts_.clear();
   back_forward_cache_disabling_features_.reset();
   last_uploaded_bfcache_disabling_features_ = 0;
+  non_sticky_features_and_js_locations_.clear();
+  sticky_features_and_js_locations_.clear();
 }
 
-void BackForwardCacheDisablingFeatureTracker::Add(
+void BackForwardCacheDisablingFeatureTracker::AddFeatureInternal(
     SchedulingPolicy::Feature feature) {
-  uint64_t old_mask = GetActiveFeaturesTrackedForBackForwardCacheMetricsMask();
-
   ++back_forward_cache_disabling_feature_counts_[feature];
   back_forward_cache_disabling_features_.set(static_cast<size_t>(feature));
   opted_out_from_back_forward_cache_ = true;
 
-  uint64_t new_mask = GetActiveFeaturesTrackedForBackForwardCacheMetricsMask();
+  NotifyDelegateAboutFeaturesAfterCurrentTask(
+      BackForwardCacheDisablingFeatureTracker::TracingType::kBegin, feature);
+}
 
-  if (old_mask != new_mask) {
-    NotifyDelegateAboutFeaturesAfterCurrentTask(
-        BackForwardCacheDisablingFeatureTracker::TracingType::kBegin, feature);
-  }
+void BackForwardCacheDisablingFeatureTracker::AddNonStickyFeature(
+    SchedulingPolicy::Feature feature,
+    std::unique_ptr<SourceLocation> source_location,
+    FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle* handle) {
+  AddFeatureInternal(feature);
+
+  DCHECK(handle);
+  non_sticky_features_and_js_locations_.push_back(
+      handle->GetFeatureAndJSLocationBlockingBFCache());
+
+  NotifyDelegateAboutFeaturesAfterCurrentTask(
+      BackForwardCacheDisablingFeatureTracker::TracingType::kBegin, feature);
+}
+
+void BackForwardCacheDisablingFeatureTracker::AddStickyFeature(
+    SchedulingPolicy::Feature feature,
+    std::unique_ptr<SourceLocation> source_location) {
+  AddFeatureInternal(feature);
+
+  sticky_features_and_js_locations_.push_back(
+      FeatureAndJSLocationBlockingBFCache(feature, source_location.get()));
+
+  NotifyDelegateAboutFeaturesAfterCurrentTask(
+      BackForwardCacheDisablingFeatureTracker::TracingType::kBegin, feature);
 }
 
 void BackForwardCacheDisablingFeatureTracker::Remove(
-    SchedulingPolicy::Feature feature) {
-  uint64_t old_mask = GetActiveFeaturesTrackedForBackForwardCacheMetricsMask();
+    FeatureAndJSLocationBlockingBFCache feature_and_js_location) {
+  SchedulingPolicy::Feature feature = feature_and_js_location.Feature();
 
   DCHECK_GT(back_forward_cache_disabling_feature_counts_[feature], 0);
   auto it = back_forward_cache_disabling_feature_counts_.find(feature);
@@ -71,12 +93,13 @@
   opted_out_from_back_forward_cache_ =
       !back_forward_cache_disabling_feature_counts_.empty();
 
-  uint64_t new_mask = GetActiveFeaturesTrackedForBackForwardCacheMetricsMask();
+  wtf_size_t index =
+      non_sticky_features_and_js_locations_.Find(feature_and_js_location);
+  DCHECK(index != kNotFound);
+  non_sticky_features_and_js_locations_.EraseAt(index);
 
-  if (old_mask != new_mask) {
-    NotifyDelegateAboutFeaturesAfterCurrentTask(
-        BackForwardCacheDisablingFeatureTracker::TracingType::kEnd, feature);
-  }
+  NotifyDelegateAboutFeaturesAfterCurrentTask(
+      BackForwardCacheDisablingFeatureTracker::TracingType::kEnd, feature);
 }
 
 WTF::HashSet<SchedulingPolicy::Feature>
@@ -98,6 +121,17 @@
   return result;
 }
 
+BFCacheBlockingFeatureAndLocations& BackForwardCacheDisablingFeatureTracker::
+    GetActiveNonStickyFeaturesTrackedForBackForwardCache() {
+  return non_sticky_features_and_js_locations_;
+}
+
+const BFCacheBlockingFeatureAndLocations&
+BackForwardCacheDisablingFeatureTracker::
+    GetActiveStickyFeaturesTrackedForBackForwardCache() const {
+  return sticky_features_and_js_locations_;
+}
+
 void BackForwardCacheDisablingFeatureTracker::
     NotifyDelegateAboutFeaturesAfterCurrentTask(
         TracingType tracing_type,
@@ -133,7 +167,9 @@
   if (mask == last_uploaded_bfcache_disabling_features_)
     return;
   last_uploaded_bfcache_disabling_features_ = mask;
-  delegate_->UpdateBackForwardCacheDisablingFeatures(mask);
+  delegate_->UpdateBackForwardCacheDisablingFeatures(
+      mask, non_sticky_features_and_js_locations_,
+      sticky_features_and_js_locations_);
 }
 
 }  // namespace scheduler
diff --git a/third_party/blink/renderer/platform/scheduler/common/back_forward_cache_disabling_feature_tracker.h b/third_party/blink/renderer/platform/scheduler/common/back_forward_cache_disabling_feature_tracker.h
index 2193bc1..dd11e4c 100644
--- a/third_party/blink/renderer/platform/scheduler/common/back_forward_cache_disabling_feature_tracker.h
+++ b/third_party/blink/renderer/platform/scheduler/common/back_forward_cache_disabling_feature_tracker.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_COMMON_BACK_FORWARD_CACHE_DISABLING_FEATURE_TRACKER_H_
 
 #include <bitset>
+#include <utility>
 
 #include "base/containers/flat_map.h"
 #include "base/memory/weak_ptr.h"
@@ -17,6 +18,9 @@
 namespace blink {
 namespace scheduler {
 
+using BFCacheBlockingFeatureAndLocations =
+    FrameOrWorkerScheduler::BFCacheBlockingFeatureAndLocations;
+
 class ThreadSchedulerBase;
 
 // Keeps track of feature usage that disables back/forward cache.
@@ -45,10 +49,28 @@
   void Reset();
 
   // Called when a usage of |feature| is added.
-  void Add(SchedulingPolicy::Feature feature);
+  // TODO(crbug.com/1366675): Remove this function and replace the bitmask and a
+  // vector to count blocking features with
+  // |non_sticky_features_and_js_locations_| and
+  // |sticky_features_and_js_locations_|.
+  void AddFeatureInternal(SchedulingPolicy::Feature feature);
 
-  // Called when one usage of |feature| is removed.
-  void Remove(SchedulingPolicy::Feature feature);
+  // Called when a usage of |feature| is added.
+  // |feature| should be a non-sticky feature.
+  void AddNonStickyFeature(
+      SchedulingPolicy::Feature feature,
+      std::unique_ptr<SourceLocation> source_location = nullptr,
+      FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle* handle =
+          nullptr);
+
+  // Called when a usage of |feature| is added.
+  // |feature| should be a sticky feature.
+  void AddStickyFeature(
+      SchedulingPolicy::Feature feature,
+      std::unique_ptr<SourceLocation> source_location = nullptr);
+
+  // Called when one usage of feature is removed.
+  void Remove(FeatureAndJSLocationBlockingBFCache feature_and_js_location);
 
   // Gets a hash set of feature usages for metrics.
   WTF::HashSet<SchedulingPolicy::Feature>
@@ -57,13 +79,21 @@
   // Gets a hash set of feature usages for metrics as a bitmap.
   uint64_t GetActiveFeaturesTrackedForBackForwardCacheMetricsMask() const;
 
+  // Gets a list of non sticky features and their JS locations.
+  BFCacheBlockingFeatureAndLocations&
+  GetActiveNonStickyFeaturesTrackedForBackForwardCache();
+
+  // Gets a list of sticky features and their JS locations.
+  const BFCacheBlockingFeatureAndLocations&
+  GetActiveStickyFeaturesTrackedForBackForwardCache() const;
+
   // Notifies the delegate about the change in the set of active features.
   // The scheduler calls this function when needed after each task finishes,
-  // grouping multiple OnStartedUsingFeature/OnStoppedUsingFeature into
-  // one call to the delegate (which is generally expected to upload them to
-  // the browser process).
-  // No calls will be issued to the delegate if the set of features didn't
-  // change since the previous call.
+  // grouping multiple
+  // OnStartedUsing(Non)StickyFeature/OnStoppedUsing(Non)StickyFeature into one
+  // call to the delegate (which is generally expected to upload them to the
+  // browser process). No calls will be issued to the delegate if the set of
+  // features didn't change since the previous call.
   void ReportFeaturesToDelegate();
 
  private:
@@ -78,6 +108,7 @@
 
   base::flat_map<SchedulingPolicy::Feature, int>
       back_forward_cache_disabling_feature_counts_{};
+  // TODO(crbug.com/1366675): Remove back_forward_cache_disabling_features_.
   std::bitset<static_cast<size_t>(SchedulingPolicy::Feature::kMaxValue) + 1>
       back_forward_cache_disabling_features_{};
   TraceableState<bool, TracingCategory::kInfo>
@@ -88,6 +119,9 @@
   uint64_t last_uploaded_bfcache_disabling_features_ = 0;
   bool feature_report_scheduled_ = false;
 
+  BFCacheBlockingFeatureAndLocations non_sticky_features_and_js_locations_;
+  BFCacheBlockingFeatureAndLocations sticky_features_and_js_locations_;
+
   FrameOrWorkerScheduler::Delegate* delegate_ = nullptr;
   ThreadSchedulerBase* scheduler_;
 
diff --git a/third_party/blink/renderer/platform/scheduler/common/back_forward_cache_disabling_feature_tracker_unittest.cc b/third_party/blink/renderer/platform/scheduler/common/back_forward_cache_disabling_feature_tracker_unittest.cc
index fe9f6a7..535e7c7 100644
--- a/third_party/blink/renderer/platform/scheduler/common/back_forward_cache_disabling_feature_tracker_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/back_forward_cache_disabling_feature_tracker_unittest.cc
@@ -7,6 +7,11 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+#include "third_party/blink/renderer/platform/bindings/source_location.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h"
+#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
+
 namespace blink {
 namespace scheduler {
 
@@ -21,6 +26,110 @@
 };
 
 TEST_F(BackForwardCacheDisablingFeatureTrackerTest, AddAndRemove) {
+  SchedulingPolicy::Feature feature_socket =
+      SchedulingPolicy::Feature::kWebSocket;
+  SchedulingPolicy::Feature feature_webrtc = SchedulingPolicy::Feature::kWebRTC;
+  const String& url = "https://a.com";
+  const String& function = "";
+  unsigned line_number = 1;
+  unsigned column_number = 1;
+
+  std::unique_ptr<SourceLocation> source_location_socket =
+      std::make_unique<SourceLocation>(url, function, line_number,
+                                       column_number, nullptr, 0);
+  std::unique_ptr<SourceLocation> source_location_webrtc =
+      std::make_unique<SourceLocation>(url, function, line_number,
+                                       column_number, nullptr, 0);
+  std::unique_ptr<SourceLocation> source_location_socket_second =
+      std::make_unique<SourceLocation>(url, function, line_number,
+                                       column_number, nullptr, 0);
+
+  FeatureAndJSLocationBlockingBFCache feature_and_js_location_socket =
+      FeatureAndJSLocationBlockingBFCache(feature_socket, url, function,
+                                          line_number, column_number);
+  FeatureAndJSLocationBlockingBFCache feature_and_js_location_webrtc =
+      FeatureAndJSLocationBlockingBFCache(feature_webrtc, url, function,
+                                          line_number, column_number);
+
+  BackForwardCacheDisablingFeatureTracker tracker(tracing_controller(),
+                                                  nullptr);
+
+  EXPECT_THAT(tracker.GetActiveFeaturesTrackedForBackForwardCacheMetrics(),
+              testing::UnorderedElementsAre());
+  EXPECT_THAT(tracker.GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(),
+              0);
+
+  FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle handle_socket =
+      FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle(
+          feature_socket, SchedulingPolicy(), source_location_socket->Clone(),
+          nullptr);
+  FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle handle_webrtc =
+      FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle(
+          feature_webrtc, SchedulingPolicy(), source_location_webrtc->Clone(),
+          nullptr);
+  FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle
+      handle_socket_second =
+          FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle(
+              feature_socket, SchedulingPolicy(),
+              source_location_socket_second->Clone(), nullptr);
+
+  BFCacheBlockingFeatureAndLocations& stored_feature_and_js_location =
+      tracker.GetActiveNonStickyFeaturesTrackedForBackForwardCache();
+
+  // Add kWebSocket.
+  tracker.AddNonStickyFeature(feature_socket, std::move(source_location_socket),
+                              &handle_socket);
+  EXPECT_NE(stored_feature_and_js_location.Find(feature_and_js_location_socket),
+            kNotFound);
+
+  // Add kWebRTC.
+  tracker.AddNonStickyFeature(feature_webrtc, std::move(source_location_webrtc),
+                              &handle_webrtc);
+  EXPECT_NE(stored_feature_and_js_location.Find(feature_and_js_location_webrtc),
+            kNotFound);
+
+  // Add kWebSocket again.
+  tracker.AddNonStickyFeature(feature_socket,
+                              std::move(source_location_socket_second),
+                              &handle_socket_second);
+  EXPECT_NE(stored_feature_and_js_location.Find(feature_and_js_location_socket),
+            kNotFound);
+
+  // Remove kWebSocket.
+  tracker.Remove(feature_and_js_location_socket);
+  EXPECT_TRUE(
+      stored_feature_and_js_location.Contains(feature_and_js_location_socket));
+  EXPECT_EQ(stored_feature_and_js_location.size(), 2u);
+
+  // Remove kWebRTC.
+  tracker.Remove(feature_and_js_location_webrtc);
+  EXPECT_FALSE(
+      stored_feature_and_js_location.Contains(feature_and_js_location_webrtc));
+  EXPECT_EQ(stored_feature_and_js_location.size(), 1u);
+
+  // Remove kWebSocket again.
+  tracker.Remove(feature_and_js_location_socket);
+  EXPECT_FALSE(
+      stored_feature_and_js_location.Contains(feature_and_js_location_socket));
+  EXPECT_TRUE(stored_feature_and_js_location.empty());
+}
+
+TEST_F(BackForwardCacheDisablingFeatureTrackerTest, AddStickyFeature) {
+  SchedulingPolicy::Feature feature =
+      SchedulingPolicy::Feature::kMainResourceHasCacheControlNoCache;
+  const String& url = "https://a.com";
+  const String& function = "";
+  unsigned line_number = 1;
+  unsigned column_number = 1;
+
+  std::unique_ptr<SourceLocation> source_location =
+      std::make_unique<SourceLocation>(url, function, line_number,
+                                       column_number, nullptr, 0);
+
+  FeatureAndJSLocationBlockingBFCache feature_and_js_location =
+      FeatureAndJSLocationBlockingBFCache(feature, url, function, line_number,
+                                          column_number);
+
   BackForwardCacheDisablingFeatureTracker tracker(tracing_controller(),
                                                   nullptr);
 
@@ -30,62 +139,10 @@
               0);
 
   // Add kWebSocket.
-  tracker.Add(SchedulingPolicy::Feature::kWebSocket);
-  EXPECT_THAT(
-      tracker.GetActiveFeaturesTrackedForBackForwardCacheMetrics(),
-      testing::UnorderedElementsAre(SchedulingPolicy::Feature::kWebSocket));
-  EXPECT_THAT(
-      tracker.GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(),
-      1 << static_cast<uint64_t>(SchedulingPolicy::Feature::kWebSocket));
-
-  // Add kWebRTC.
-  tracker.Add(SchedulingPolicy::Feature::kWebRTC);
-  EXPECT_THAT(
-      tracker.GetActiveFeaturesTrackedForBackForwardCacheMetrics(),
-      testing::UnorderedElementsAre(SchedulingPolicy::Feature::kWebSocket,
-                                    SchedulingPolicy::Feature::kWebRTC));
-  EXPECT_THAT(
-      tracker.GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(),
-      (1 << static_cast<uint64_t>(SchedulingPolicy::Feature::kWebSocket)) |
-          (1 << static_cast<uint64_t>(SchedulingPolicy::Feature::kWebRTC)));
-
-  // Add kWebSocket again.
-  tracker.Add(SchedulingPolicy::Feature::kWebSocket);
-  EXPECT_THAT(
-      tracker.GetActiveFeaturesTrackedForBackForwardCacheMetrics(),
-      testing::UnorderedElementsAre(SchedulingPolicy::Feature::kWebSocket,
-                                    SchedulingPolicy::Feature::kWebRTC));
-  EXPECT_THAT(
-      tracker.GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(),
-      (1 << static_cast<uint64_t>(SchedulingPolicy::Feature::kWebSocket)) |
-          (1 << static_cast<uint64_t>(SchedulingPolicy::Feature::kWebRTC)));
-
-  // Remove kWebRTC.
-  tracker.Remove(SchedulingPolicy::Feature::kWebRTC);
-  EXPECT_THAT(
-      tracker.GetActiveFeaturesTrackedForBackForwardCacheMetrics(),
-      testing::UnorderedElementsAre(SchedulingPolicy::Feature::kWebSocket));
-  EXPECT_THAT(
-      tracker.GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(),
-      1 << static_cast<uint64_t>(SchedulingPolicy::Feature::kWebSocket));
-
-  // Remove kWebSocket. As kWebSocket was added twice, removing it once doesn't
-  // change the metrics result.
-  tracker.Remove(SchedulingPolicy::Feature::kWebSocket);
-  EXPECT_THAT(
-      tracker.GetActiveFeaturesTrackedForBackForwardCacheMetrics(),
-      testing::UnorderedElementsAre(SchedulingPolicy::Feature::kWebSocket));
-  EXPECT_THAT(
-      tracker.GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(),
-      1 << static_cast<uint64_t>(SchedulingPolicy::Feature::kWebSocket));
-
-  // Remove kWebSocket again.
-  tracker.Remove(SchedulingPolicy::Feature::kWebSocket);
-  EXPECT_THAT(tracker.GetActiveFeaturesTrackedForBackForwardCacheMetrics(),
-              testing::UnorderedElementsAre());
-  EXPECT_THAT(tracker.GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(),
-              0);
+  tracker.AddStickyFeature(feature, std::move(source_location));
+  EXPECT_TRUE(
+      tracker.GetActiveStickyFeaturesTrackedForBackForwardCache().Contains(
+          feature_and_js_location));
 }
-
 }  // namespace scheduler
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc b/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc
index 06070001..83e301e2 100644
--- a/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc
@@ -125,11 +125,18 @@
     return nullptr;
   }
   ukm::SourceId GetUkmSourceId() override { return ukm::kInvalidSourceId; }
-  void OnStartedUsingFeature(SchedulingPolicy::Feature feature,
-                             const SchedulingPolicy& policy) override {}
-  void OnStoppedUsingFeature(SchedulingPolicy::Feature feature,
-                             const SchedulingPolicy& policy) override {}
-  base::WeakPtr<FrameOrWorkerScheduler> GetSchedulingAffectingFeatureWeakPtr()
+  void OnStartedUsingNonStickyFeature(
+      SchedulingPolicy::Feature feature,
+      const SchedulingPolicy& policy,
+      std::unique_ptr<SourceLocation> source_location,
+      SchedulingAffectingFeatureHandle* handle) override {}
+  void OnStartedUsingStickyFeature(
+      SchedulingPolicy::Feature feature,
+      const SchedulingPolicy& policy,
+      std::unique_ptr<SourceLocation> source_location) override {}
+  void OnStoppedUsingNonStickyFeature(
+      SchedulingAffectingFeatureHandle* handle) override {}
+  base::WeakPtr<FrameOrWorkerScheduler> GetFrameOrWorkerSchedulerWeakPtr()
       override {
     return weak_ptr_factory_.GetWeakPtr();
   }
diff --git a/third_party/blink/renderer/platform/scheduler/common/frame_or_worker_scheduler.cc b/third_party/blink/renderer/platform/scheduler/common/frame_or_worker_scheduler.cc
index ddf9fcfd..9f8d737 100644
--- a/third_party/blink/renderer/platform/scheduler/common/frame_or_worker_scheduler.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/frame_or_worker_scheduler.cc
@@ -43,16 +43,23 @@
     SchedulingAffectingFeatureHandle(
         SchedulingPolicy::Feature feature,
         SchedulingPolicy policy,
+        std::unique_ptr<SourceLocation> source_location,
         base::WeakPtr<FrameOrWorkerScheduler> scheduler)
-    : feature_(feature), policy_(policy), scheduler_(std::move(scheduler)) {
+    : feature_(feature),
+      policy_(policy),
+      feature_and_js_location_(feature, source_location.get()),
+      scheduler_(std::move(scheduler)) {
   if (!scheduler_)
     return;
-  scheduler_->OnStartedUsingFeature(feature_, policy_);
+  scheduler_->OnStartedUsingNonStickyFeature(feature_, policy_,
+                                             std::move(source_location), this);
 }
 
 FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle::
     SchedulingAffectingFeatureHandle(SchedulingAffectingFeatureHandle&& other)
-    : feature_(other.feature_), scheduler_(std::move(other.scheduler_)) {
+    : feature_(other.feature_),
+      feature_and_js_location_(other.feature_and_js_location_),
+      scheduler_(std::move(other.scheduler_)) {
   other.scheduler_ = nullptr;
 }
 
@@ -61,11 +68,23 @@
     SchedulingAffectingFeatureHandle&& other) {
   feature_ = other.feature_;
   policy_ = std::move(other.policy_);
+  feature_and_js_location_ = other.feature_and_js_location_;
   scheduler_ = std::move(other.scheduler_);
   other.scheduler_ = nullptr;
   return *this;
 }
 
+SchedulingPolicy
+FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle::GetPolicy() const {
+  return policy_;
+}
+
+const FeatureAndJSLocationBlockingBFCache& FrameOrWorkerScheduler::
+    SchedulingAffectingFeatureHandle::GetFeatureAndJSLocationBlockingBFCache()
+        const {
+  return feature_and_js_location_;
+}
+
 FrameOrWorkerScheduler::FrameOrWorkerScheduler() {}
 
 FrameOrWorkerScheduler::~FrameOrWorkerScheduler() {
@@ -81,13 +100,13 @@
     // CaptureSourceLocation() detects the location of JS blocking BFCache if JS
     // is running.
     if (v8::Isolate* isolate = v8::Isolate::TryGetCurrent()) {
-      // TODO(crbug.com/1366675): Add source location into
-      // SchedulingAffectingFeatureHandle to pass it to the browser.
-      std::unique_ptr<SourceLocation> source_location = CaptureSourceLocation();
+      return SchedulingAffectingFeatureHandle(
+          feature, policy, CaptureSourceLocation(),
+          GetFrameOrWorkerSchedulerWeakPtr());
     }
   }
-  return SchedulingAffectingFeatureHandle(
-      feature, policy, GetSchedulingAffectingFeatureWeakPtr());
+  return SchedulingAffectingFeatureHandle(feature, policy, nullptr,
+                                          GetFrameOrWorkerSchedulerWeakPtr());
 }
 
 void FrameOrWorkerScheduler::RegisterStickyFeature(
@@ -95,16 +114,13 @@
     SchedulingPolicy policy) {
   DCHECK(scheduler::IsFeatureSticky(feature));
   if (IsRegisterJSSourceLocationBlockingBFCache()) {
-    // Check if V8 is currently running an isolate.
     // CaptureSourceLocation() detects the location of JS blocking BFCache if JS
     // is running.
     if (v8::Isolate* isolate = v8::Isolate::TryGetCurrent()) {
-      // TODO(crbug.com/1366675): Add source location into
-      // SchedulingAffectingFeatureHandle to pass it to the browser.
-      std::unique_ptr<SourceLocation> source_location = CaptureSourceLocation();
+      OnStartedUsingStickyFeature(feature, policy, CaptureSourceLocation());
     }
   }
-  OnStartedUsingFeature(feature, policy);
+  OnStartedUsingStickyFeature(feature, policy, nullptr);
 }
 
 std::unique_ptr<FrameOrWorkerScheduler::LifecycleObserverHandle>
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/attribution_group.h b/third_party/blink/renderer/platform/scheduler/main_thread/attribution_group.h
index 8f3f7fc6..e5975ee 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/attribution_group.h
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/attribution_group.h
@@ -54,9 +54,8 @@
 namespace WTF {
 
 template <>
-struct DefaultHash<blink::scheduler::AttributionGroup> {
-  using Hash = blink::scheduler::AttributionGroupHash;
-};
+struct DefaultHash<blink::scheduler::AttributionGroup>
+    : blink::scheduler::AttributionGroupHash {};
 
 template <>
 struct HashTraits<blink::scheduler::AttributionGroup>
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
index 8a1dfdff..c7c3efc 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
@@ -617,24 +617,43 @@
   back_forward_cache_disabling_feature_tracker_.Reset();
 }
 
-void FrameSchedulerImpl::OnStartedUsingFeature(
+void FrameSchedulerImpl::OnStartedUsingNonStickyFeature(
     SchedulingPolicy::Feature feature,
-    const SchedulingPolicy& policy) {
+    const SchedulingPolicy& policy,
+    std::unique_ptr<SourceLocation> source_location,
+    SchedulingAffectingFeatureHandle* handle) {
   if (policy.disable_aggressive_throttling)
     OnAddedAggressiveThrottlingOptOut();
-  if (policy.disable_back_forward_cache)
-    back_forward_cache_disabling_feature_tracker_.Add(feature);
+  if (policy.disable_back_forward_cache) {
+    back_forward_cache_disabling_feature_tracker_.AddNonStickyFeature(
+        feature, std::move(source_location), handle);
+  }
   if (policy.disable_align_wake_ups)
     DisableAlignWakeUpsForProcess();
 }
 
-void FrameSchedulerImpl::OnStoppedUsingFeature(
+void FrameSchedulerImpl::OnStartedUsingStickyFeature(
     SchedulingPolicy::Feature feature,
-    const SchedulingPolicy& policy) {
+    const SchedulingPolicy& policy,
+    std::unique_ptr<SourceLocation> source_location) {
   if (policy.disable_aggressive_throttling)
+    OnAddedAggressiveThrottlingOptOut();
+  if (policy.disable_back_forward_cache) {
+    back_forward_cache_disabling_feature_tracker_.AddStickyFeature(
+        feature, std::move(source_location));
+  }
+  if (policy.disable_align_wake_ups)
+    DisableAlignWakeUpsForProcess();
+}
+
+void FrameSchedulerImpl::OnStoppedUsingNonStickyFeature(
+    SchedulingAffectingFeatureHandle* handle) {
+  if (handle->GetPolicy().disable_aggressive_throttling)
     OnRemovedAggressiveThrottlingOptOut();
-  if (policy.disable_back_forward_cache)
-    back_forward_cache_disabling_feature_tracker_.Remove(feature);
+  if (handle->GetPolicy().disable_back_forward_cache) {
+    back_forward_cache_disabling_feature_tracker_.Remove(
+        handle->GetFeatureAndJSLocationBlockingBFCache());
+  }
 }
 
 base::WeakPtr<FrameScheduler> FrameSchedulerImpl::GetWeakPtr() {
@@ -1163,7 +1182,7 @@
 }
 
 base::WeakPtr<FrameOrWorkerScheduler>
-FrameSchedulerImpl::GetSchedulingAffectingFeatureWeakPtr() {
+FrameSchedulerImpl::GetFrameOrWorkerSchedulerWeakPtr() {
   // We reset feature sets upon frame navigation, so having a document-bound
   // weak pointer ensures that the feature handle associated with previous
   // document can't influence the new one.
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h
index 15ae2fd..7a76801 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h
@@ -136,10 +136,17 @@
   std::unique_ptr<blink::mojom::blink::PauseSubresourceLoadingHandle>
   GetPauseSubresourceLoadingHandle() override;
 
-  void OnStartedUsingFeature(SchedulingPolicy::Feature feature,
-                             const SchedulingPolicy& policy) override;
-  void OnStoppedUsingFeature(SchedulingPolicy::Feature feature,
-                             const SchedulingPolicy& policy) override;
+  void OnStartedUsingNonStickyFeature(
+      SchedulingPolicy::Feature feature,
+      const SchedulingPolicy& policy,
+      std::unique_ptr<SourceLocation> source_location,
+      SchedulingAffectingFeatureHandle* handle) override;
+  void OnStartedUsingStickyFeature(
+      SchedulingPolicy::Feature feature,
+      const SchedulingPolicy& policy,
+      std::unique_ptr<SourceLocation> source_location) override;
+  void OnStoppedUsingNonStickyFeature(
+      SchedulingAffectingFeatureHandle* handle) override;
 
   base::WeakPtr<FrameScheduler> GetWeakPtr() override;
   base::WeakPtr<const FrameSchedulerImpl> GetWeakPtr() const;
@@ -274,7 +281,7 @@
   // a mask instead of a set.
   uint64_t GetActiveFeaturesTrackedForBackForwardCacheMetricsMask() const;
 
-  base::WeakPtr<FrameOrWorkerScheduler> GetSchedulingAffectingFeatureWeakPtr()
+  base::WeakPtr<FrameOrWorkerScheduler> GetFrameOrWorkerSchedulerWeakPtr()
       override;
 
   void MoveTaskQueuesToCorrectWakeUpBudgetPool();
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
index 8d6b04d4..2cc7e63 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
@@ -183,8 +183,11 @@
   const base::UnguessableToken& GetAgentClusterId() const override {
     return base::UnguessableToken::Null();
   }
-
-  MOCK_METHOD1(UpdateBackForwardCacheDisablingFeatures, void(uint64_t));
+  MOCK_METHOD(void,
+              UpdateBackForwardCacheDisablingFeatures,
+              (uint64_t,
+               const BFCacheBlockingFeatureAndLocations&,
+               const BFCacheBlockingFeatureAndLocations&));
 
   int update_task_time_calls_ = 0;
 };
@@ -2118,9 +2121,19 @@
                         (1 << static_cast<size_t>(
                              SchedulingPolicy::Feature::
                                  kMainResourceHasCacheControlNoStore)) |
-                        (1 << static_cast<size_t>(
-                             SchedulingPolicy::Feature::
-                                 kMainResourceHasCacheControlNoCache))));
+                            (1 << static_cast<size_t>(
+                                 SchedulingPolicy::Feature::
+                                     kMainResourceHasCacheControlNoCache)),
+                        BFCacheBlockingFeatureAndLocations(),
+                        BFCacheBlockingFeatureAndLocations(
+                            {FeatureAndJSLocationBlockingBFCache(
+                                 SchedulingPolicy::Feature::
+                                     kMainResourceHasCacheControlNoStore,
+                                 nullptr),
+                             FeatureAndJSLocationBlockingBFCache(
+                                 SchedulingPolicy::Feature::
+                                     kMainResourceHasCacheControlNoCache,
+                                 nullptr)})));
               },
               frame_scheduler_.get(), frame_scheduler_delegate_.get()));
 
@@ -2133,7 +2146,9 @@
   ResetFrameScheduler(/*is_in_embedded_frame_tree=*/false,
                       FrameScheduler::FrameType::kMainFrame);
 
-  FeatureHandle feature_handle;
+  FeatureHandle feature_handle(frame_scheduler_->RegisterFeature(
+      SchedulingPolicy::Feature::kWebSocket,
+      {SchedulingPolicy::DisableBackForwardCache()}));
 
   frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimerImmediate)
       ->PostTask(
@@ -2143,15 +2158,17 @@
                  testing::StrictMock<FrameSchedulerDelegateForTesting>*
                      delegate,
                  FeatureHandle* feature_handle) {
-                *feature_handle = frame_scheduler->RegisterFeature(
-                    SchedulingPolicy::Feature::kWebSocket,
-                    {SchedulingPolicy::DisableBackForwardCache()});
                 // Ensure that the feature upload is delayed.
                 testing::Mock::VerifyAndClearExpectations(delegate);
-                EXPECT_CALL(*delegate,
-                            UpdateBackForwardCacheDisablingFeatures(
-                                (1 << static_cast<size_t>(
-                                     SchedulingPolicy::Feature::kWebSocket))));
+                EXPECT_CALL(
+                    *delegate,
+                    UpdateBackForwardCacheDisablingFeatures(
+                        (1 << static_cast<size_t>(
+                             SchedulingPolicy::Feature::kWebSocket)),
+                        BFCacheBlockingFeatureAndLocations(
+                            {feature_handle
+                                 ->GetFeatureAndJSLocationBlockingBFCache()}),
+                        BFCacheBlockingFeatureAndLocations()));
               },
               frame_scheduler_.get(), frame_scheduler_delegate_.get(),
               &feature_handle));
@@ -2169,7 +2186,9 @@
                        testing::Mock::VerifyAndClearExpectations(delegate);
                        EXPECT_CALL(
                            *delegate,
-                           UpdateBackForwardCacheDisablingFeatures(testing::_))
+                           UpdateBackForwardCacheDisablingFeatures(
+                               testing::_, BFCacheBlockingFeatureAndLocations(),
+                               BFCacheBlockingFeatureAndLocations()))
                            .Times(0);
                      },
                      frame_scheduler_.get(), frame_scheduler_delegate_.get(),
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
index 051cb30..80bf58e4 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
@@ -59,7 +59,6 @@
 using ::base::sequence_manager::FakeTask;
 using ::base::sequence_manager::FakeTaskTiming;
 using blink::WebInputEvent;
-using FeatureAndParams = ::base::test::FeatureRefAndParams;
 using ::testing::InSequence;
 using ::testing::Mock;
 using ::testing::NiceMock;
@@ -402,7 +401,7 @@
   }
 
   explicit MainThreadSchedulerImplTest(
-      std::vector<FeatureAndParams> features_to_enable) {
+      std::vector<::base::test::FeatureRefAndParams> features_to_enable) {
     feature_list_.InitWithFeaturesAndParameters(features_to_enable, {});
   }
 
diff --git a/third_party/blink/renderer/platform/scheduler/public/DEPS b/third_party/blink/renderer/platform/scheduler/public/DEPS
index 1361ae43..ad6c9e8 100644
--- a/third_party/blink/renderer/platform/scheduler/public/DEPS
+++ b/third_party/blink/renderer/platform/scheduler/public/DEPS
@@ -1,4 +1,7 @@
 specific_include_rules = {
+  "feature_and_js_location_blocking_bfcache.h": [
+    "+third_party/blink/renderer/platform/bindings/source_location.h",
+  ],
   "thread.h": [
     "+base/task/task_observer.h",
   ]
diff --git a/third_party/blink/renderer/platform/scheduler/public/feature_and_js_location_blocking_bfcache.cc b/third_party/blink/renderer/platform/scheduler/public/feature_and_js_location_blocking_bfcache.cc
new file mode 100644
index 0000000..e2de11b
--- /dev/null
+++ b/third_party/blink/renderer/platform/scheduler/public/feature_and_js_location_blocking_bfcache.cc
@@ -0,0 +1,48 @@
+// 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.
+
+#include "third_party/blink/renderer/platform/scheduler/public/feature_and_js_location_blocking_bfcache.h"
+
+namespace blink {
+
+FeatureAndJSLocationBlockingBFCache::FeatureAndJSLocationBlockingBFCache(
+    SchedulingPolicy::Feature feature,
+    const String& url,
+    const String& function,
+    unsigned line_number,
+    unsigned column_number)
+    : feature_(feature),
+      url_(url),
+      function_(function),
+      line_number_(line_number),
+      column_number_(column_number) {}
+
+FeatureAndJSLocationBlockingBFCache::FeatureAndJSLocationBlockingBFCache(
+    SchedulingPolicy::Feature feature,
+    const SourceLocation* source_location)
+    : feature_(feature) {
+  if (source_location) {
+    url_ = source_location->Url();
+    function_ = source_location->Function();
+    line_number_ = source_location->LineNumber();
+    column_number_ = source_location->ColumnNumber();
+  } else {
+    url_ = g_empty_string;
+    function_ = g_empty_string;
+    line_number_ = 0;
+    column_number_ = 0;
+  }
+}
+
+FeatureAndJSLocationBlockingBFCache::~FeatureAndJSLocationBlockingBFCache() =
+    default;
+
+bool FeatureAndJSLocationBlockingBFCache::operator==(
+    const FeatureAndJSLocationBlockingBFCache& other) const {
+  return (feature_ == other.feature_ && url_ == other.url_ &&
+          function_ == other.function_ && line_number_ == other.line_number_ &&
+          column_number_ == other.column_number_);
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/platform/scheduler/public/feature_and_js_location_blocking_bfcache.h b/third_party/blink/renderer/platform/scheduler/public/feature_and_js_location_blocking_bfcache.h
new file mode 100644
index 0000000..3cc326f0
--- /dev/null
+++ b/third_party/blink/renderer/platform/scheduler/public/feature_and_js_location_blocking_bfcache.h
@@ -0,0 +1,51 @@
+// 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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_FEATURE_AND_JS_LOCATION_BLOCKING_BFCACHE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_FEATURE_AND_JS_LOCATION_BLOCKING_BFCACHE_H_
+
+#include "third_party/blink/renderer/platform/bindings/source_location.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/scheduler/public/scheduling_policy.h"
+
+namespace blink {
+
+// A location in JS code.
+// BackForwardCacheDisablingFeatureTracker in
+// scheduler/common/back_forward_cache_disabling_feature_tracker.h creates
+// FeatureAndJSLocationBlockingBFCache from SourceLocation and send it to the
+// browser.
+class PLATFORM_EXPORT FeatureAndJSLocationBlockingBFCache {
+ public:
+  FeatureAndJSLocationBlockingBFCache() = default;
+  FeatureAndJSLocationBlockingBFCache(SchedulingPolicy::Feature feature,
+                                      const String& url,
+                                      const String& function,
+                                      unsigned line_number,
+                                      unsigned column_number);
+  FeatureAndJSLocationBlockingBFCache(SchedulingPolicy::Feature feature,
+                                      const SourceLocation* source_location);
+  FeatureAndJSLocationBlockingBFCache(
+      const FeatureAndJSLocationBlockingBFCache&) = default;
+  FeatureAndJSLocationBlockingBFCache& operator=(
+      const FeatureAndJSLocationBlockingBFCache&) = default;
+  ~FeatureAndJSLocationBlockingBFCache();
+  bool operator==(const FeatureAndJSLocationBlockingBFCache& other) const;
+  SchedulingPolicy::Feature Feature() const { return feature_; }
+  const String& Url() const { return url_; }
+  const String& Function() const { return function_; }
+  unsigned LineNumber() const { return line_number_; }
+  unsigned ColumnNumber() const { return column_number_; }
+
+ private:
+  SchedulingPolicy::Feature feature_ = SchedulingPolicy::Feature::kMinValue;
+  String url_;
+  String function_;
+  unsigned line_number_;
+  unsigned column_number_;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_FEATURE_AND_JS_LOCATION_BLOCKING_BFCACHE_H_
diff --git a/third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h b/third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h
index 276bb04..fa6b6fc 100644
--- a/third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h
+++ b/third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h
@@ -10,6 +10,7 @@
 #include "base/task/single_thread_task_runner.h"
 #include "base/types/strong_alias.h"
 #include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/scheduler/public/feature_and_js_location_blocking_bfcache.h"
 #include "third_party/blink/renderer/platform/scheduler/public/scheduling_lifecycle_state.h"
 #include "third_party/blink/renderer/platform/scheduler/public/scheduling_policy.h"
 #include "third_party/blink/renderer/platform/scheduler/public/web_scheduling_priority.h"
@@ -47,11 +48,19 @@
 
   // RAII handle which should be kept alive as long as the feature is active
   // and the policy should be applied.
+  // TODO(crbug.com/1366675): Rename SchedulingAffectingFeatureHandle to
+  // NonStickyFeatureHandle and move it to
+  // back_forward_cache_disabling_feature_tracker.h.
   class PLATFORM_EXPORT SchedulingAffectingFeatureHandle {
     DISALLOW_NEW();
 
    public:
     SchedulingAffectingFeatureHandle() = default;
+    SchedulingAffectingFeatureHandle(
+        SchedulingPolicy::Feature feature,
+        SchedulingPolicy policy,
+        std::unique_ptr<SourceLocation> source_location,
+        base::WeakPtr<FrameOrWorkerScheduler>);
     SchedulingAffectingFeatureHandle(SchedulingAffectingFeatureHandle&&);
     SchedulingAffectingFeatureHandle& operator=(
         SchedulingAffectingFeatureHandle&&);
@@ -62,31 +71,43 @@
 
     inline void reset() {
       if (scheduler_)
-        scheduler_->OnStoppedUsingFeature(feature_, policy_);
+        scheduler_->OnStoppedUsingNonStickyFeature(this);
       scheduler_ = nullptr;
     }
 
+    SchedulingPolicy GetPolicy() const;
+
+    const FeatureAndJSLocationBlockingBFCache&
+    GetFeatureAndJSLocationBlockingBFCache() const;
+
    private:
     friend class FrameOrWorkerScheduler;
 
-    SchedulingAffectingFeatureHandle(SchedulingPolicy::Feature feature,
-                                     SchedulingPolicy policy,
-                                     base::WeakPtr<FrameOrWorkerScheduler>);
-
     SchedulingPolicy::Feature feature_ = SchedulingPolicy::Feature::kMaxValue;
     SchedulingPolicy policy_;
+    FeatureAndJSLocationBlockingBFCache feature_and_js_location_;
     base::WeakPtr<FrameOrWorkerScheduler> scheduler_;
   };
 
+  using BFCacheBlockingFeatureAndLocations =
+      WTF::Vector<FeatureAndJSLocationBlockingBFCache>;
+
   class PLATFORM_EXPORT Delegate {
    public:
+    using BFCacheBlockingFeatureAndLocations =
+        FrameOrWorkerScheduler::BFCacheBlockingFeatureAndLocations;
     virtual ~Delegate() = default;
 
-    // Notifies that the list of active features for this worker has changed.
-    // See SchedulingPolicy::Feature for the list of features and the meaning
-    // of individual features.
+    // Notifies that the list of active blocking features for this worker has
+    // changed when a blocking feature and its JS location are registered or
+    // removed.
+    // TODO(crbug.com/1366675): Remove features_mask
     virtual void UpdateBackForwardCacheDisablingFeatures(
-        uint64_t features_mask) = 0;
+        uint64_t features_mask,
+        const BFCacheBlockingFeatureAndLocations&
+            non_sticky_features_and_js_locations,
+        const BFCacheBlockingFeatureAndLocations&
+            sticky_features_and_js_locations) = 0;
   };
 
   virtual ~FrameOrWorkerScheduler();
@@ -102,6 +123,9 @@
   // Usage:
   // handle = scheduler->RegisterFeature(
   //     kYourFeature, { SchedulingPolicy::DisableSomething() });
+  // TODO(crbug.com/1366675): Rename RegisterFeature to
+  // RegisterNonStickyFeature.
+
   [[nodiscard]] SchedulingAffectingFeatureHandle RegisterFeature(
       SchedulingPolicy::Feature feature,
       SchedulingPolicy policy);
@@ -152,15 +176,24 @@
     return scheduler::SchedulingLifecycleState::kNotThrottled;
   }
 
-  virtual void OnStartedUsingFeature(SchedulingPolicy::Feature feature,
-                                     const SchedulingPolicy& policy) = 0;
-  virtual void OnStoppedUsingFeature(SchedulingPolicy::Feature feature,
-                                     const SchedulingPolicy& policy) = 0;
+  // |source_location| is nullptr when JS is not running.
+  virtual void OnStartedUsingNonStickyFeature(
+      SchedulingPolicy::Feature feature,
+      const SchedulingPolicy& policy,
+      std::unique_ptr<SourceLocation> source_location,
+      SchedulingAffectingFeatureHandle* handle) = 0;
+  // |source_location| is nullptr when JS is not running.
+  virtual void OnStartedUsingStickyFeature(
+      SchedulingPolicy::Feature feature,
+      const SchedulingPolicy& policy,
+      std::unique_ptr<SourceLocation> source_location) = 0;
+  virtual void OnStoppedUsingNonStickyFeature(
+      SchedulingAffectingFeatureHandle* handle) = 0;
 
   // Gets a weak pointer for this scheduler that is reset when the influence by
   // registered features to this scheduler is reset.
   virtual base::WeakPtr<FrameOrWorkerScheduler>
-  GetSchedulingAffectingFeatureWeakPtr() = 0;
+  GetFrameOrWorkerSchedulerWeakPtr() = 0;
 
  private:
   class ObserverState {
diff --git a/third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h b/third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h
index eeb14cd..f67bd28 100644
--- a/third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h
+++ b/third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h
@@ -162,10 +162,19 @@
       bool is_web_history_inert_commit,
       FrameScheduler::NavigationType navigation_type) override {}
   void OnFirstMeaningfulPaint() override {}
-  void OnStartedUsingFeature(SchedulingPolicy::Feature feature,
-                             const SchedulingPolicy& policy) override {}
-  void OnStoppedUsingFeature(SchedulingPolicy::Feature feature,
-                             const SchedulingPolicy& policy) override {}
+  // |source_location| is nullptr when JS is not running.
+  // |handle| is nullptr when sticky feature starts to be used.
+  void OnStartedUsingNonStickyFeature(
+      SchedulingPolicy::Feature feature,
+      const SchedulingPolicy& policy,
+      std::unique_ptr<SourceLocation> source_location,
+      SchedulingAffectingFeatureHandle* handle) override {}
+  void OnStartedUsingStickyFeature(
+      SchedulingPolicy::Feature feature,
+      const SchedulingPolicy& policy,
+      std::unique_ptr<SourceLocation> source_location) override {}
+  void OnStoppedUsingNonStickyFeature(
+      SchedulingAffectingFeatureHandle* handle) override {}
   bool IsExemptFromBudgetBasedThrottling() const override {
     return is_exempt_from_throttling_;
   }
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_impl.cc
index 895b9b4..9ecbbb1 100644
--- a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_impl.cc
+++ b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_impl.cc
@@ -277,31 +277,46 @@
   return throttleable_task_queue_.get();
 }
 
-void WorkerSchedulerImpl::OnStartedUsingFeature(
+void WorkerSchedulerImpl::OnStartedUsingNonStickyFeature(
     SchedulingPolicy::Feature feature,
-    const SchedulingPolicy& policy) {
+    const SchedulingPolicy& policy,
+    std::unique_ptr<SourceLocation> source_location,
+    SchedulingAffectingFeatureHandle* handle) {
   if (policy.disable_align_wake_ups)
     scheduler::DisableAlignWakeUpsForProcess();
 
   if (!policy.disable_back_forward_cache) {
     return;
   }
-
-  back_forward_cache_disabling_feature_tracker_.Add(feature);
+  back_forward_cache_disabling_feature_tracker_.AddNonStickyFeature(
+      feature, std::move(source_location), handle);
 }
 
-void WorkerSchedulerImpl::OnStoppedUsingFeature(
+void WorkerSchedulerImpl::OnStartedUsingStickyFeature(
     SchedulingPolicy::Feature feature,
-    const SchedulingPolicy& policy) {
+    const SchedulingPolicy& policy,
+    std::unique_ptr<SourceLocation> source_location) {
+  if (policy.disable_align_wake_ups)
+    scheduler::DisableAlignWakeUpsForProcess();
+
   if (!policy.disable_back_forward_cache) {
     return;
   }
+  back_forward_cache_disabling_feature_tracker_.AddStickyFeature(
+      feature, std::move(source_location));
+}
 
-  back_forward_cache_disabling_feature_tracker_.Remove(feature);
+void WorkerSchedulerImpl::OnStoppedUsingNonStickyFeature(
+    SchedulingAffectingFeatureHandle* handle) {
+  if (!handle->GetPolicy().disable_back_forward_cache) {
+    return;
+  }
+  back_forward_cache_disabling_feature_tracker_.Remove(
+      handle->GetFeatureAndJSLocationBlockingBFCache());
 }
 
 base::WeakPtr<FrameOrWorkerScheduler>
-WorkerSchedulerImpl::GetSchedulingAffectingFeatureWeakPtr() {
+WorkerSchedulerImpl::GetFrameOrWorkerSchedulerWeakPtr() {
   return weak_factory_.GetWeakPtr();
 }
 
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_impl.h
index 4f37a3b..970961b2 100644
--- a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_impl.h
+++ b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_impl.h
@@ -56,11 +56,18 @@
 
   // FrameOrWorkerScheduler implementation:
   SchedulingLifecycleState CalculateLifecycleState(ObserverType) const override;
-  void OnStartedUsingFeature(SchedulingPolicy::Feature feature,
-                             const SchedulingPolicy& policy) override;
-  void OnStoppedUsingFeature(SchedulingPolicy::Feature feature,
-                             const SchedulingPolicy& policy) override;
-  base::WeakPtr<FrameOrWorkerScheduler> GetSchedulingAffectingFeatureWeakPtr()
+  void OnStartedUsingNonStickyFeature(
+      SchedulingPolicy::Feature feature,
+      const SchedulingPolicy& policy,
+      std::unique_ptr<SourceLocation> source_location,
+      SchedulingAffectingFeatureHandle* handle) override;
+  void OnStartedUsingStickyFeature(
+      SchedulingPolicy::Feature feature,
+      const SchedulingPolicy& policy,
+      std::unique_ptr<SourceLocation> source_location) override;
+  void OnStoppedUsingNonStickyFeature(
+      SchedulingAffectingFeatureHandle* handle) override;
+  base::WeakPtr<FrameOrWorkerScheduler> GetFrameOrWorkerSchedulerWeakPtr()
       override;
   void SetPreemptedForCooperativeScheduling(Preempted) override {}
   std::unique_ptr<WebSchedulingTaskQueue> CreateWebSchedulingTaskQueue(
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_impl_unittest.cc
index a10dae71..0eef4d7 100644
--- a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_impl_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_impl_unittest.cc
@@ -14,6 +14,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/platform/scheduler/common/throttling/cpu_time_budget_pool.h"
 #include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h"
+#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
 #include "third_party/blink/renderer/platform/scheduler/public/web_scheduling_priority.h"
 #include "third_party/blink/renderer/platform/scheduler/public/web_scheduling_task_queue.h"
 #include "third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h"
@@ -318,7 +319,11 @@
 
 class WorkerSchedulerDelegateForTesting : public WorkerScheduler::Delegate {
  public:
-  MOCK_METHOD1(UpdateBackForwardCacheDisablingFeatures, void(uint64_t));
+  MOCK_METHOD(void,
+              UpdateBackForwardCacheDisablingFeatures,
+              (uint64_t,
+               const BFCacheBlockingFeatureAndLocations&,
+               const BFCacheBlockingFeatureAndLocations&));
 };
 
 // Confirms that the feature usage in a dedicated worker is uploaded to
@@ -352,9 +357,19 @@
                                (1 << static_cast<uint64_t>(
                                     SchedulingPolicy::Feature::
                                         kMainResourceHasCacheControlNoStore)) |
-                               (1 << static_cast<uint64_t>(
-                                    SchedulingPolicy::Feature::
-                                        kMainResourceHasCacheControlNoCache))));
+                                   (1 << static_cast<uint64_t>(
+                                        SchedulingPolicy::Feature::
+                                            kMainResourceHasCacheControlNoCache)),
+                               BFCacheBlockingFeatureAndLocations(),
+                               BFCacheBlockingFeatureAndLocations(
+                                   {FeatureAndJSLocationBlockingBFCache(
+                                        SchedulingPolicy::Feature::
+                                            kMainResourceHasCacheControlNoStore,
+                                        nullptr),
+                                    FeatureAndJSLocationBlockingBFCache(
+                                        SchedulingPolicy::Feature::
+                                            kMainResourceHasCacheControlNoCache,
+                                        nullptr)})));
                      },
                      worker_scheduler_.get(), delegate.get()));
 
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler_unittest.cc b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler_unittest.cc
index a1d9382..066e14942 100644
--- a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler_unittest.cc
@@ -466,7 +466,11 @@
   void UpdateTaskTime(base::TimeDelta time) override {}
 
   void UpdateBackForwardCacheDisablingFeatures(
-      uint64_t features_mask) override {}
+      uint64_t features_mask,
+      const BFCacheBlockingFeatureAndLocations&
+          non_sticky_features_and_js_locations,
+      const BFCacheBlockingFeatureAndLocations&
+          sticky_features_and_js_locations) override {}
 
   const base::UnguessableToken& GetAgentClusterId() const override {
     return base::UnguessableToken::Null();
diff --git a/third_party/blink/renderer/platform/storage/blink_storage_key_hash.h b/third_party/blink/renderer/platform/storage/blink_storage_key_hash.h
index 4b0fcda..3498c7b 100644
--- a/third_party/blink/renderer/platform/storage/blink_storage_key_hash.h
+++ b/third_party/blink/renderer/platform/storage/blink_storage_key_hash.h
@@ -20,8 +20,7 @@
     size_t nonce_hash = nonce ? base::UnguessableTokenHash()(*nonce) : 0;
     unsigned hash_codes[] = {
       SecurityOriginHash::GetHash(storage_key->GetSecurityOrigin()),
-      DefaultHash<BlinkSchemefulSite>::Hash::GetHash(
-          storage_key->GetTopLevelSite()),
+      DefaultHash<BlinkSchemefulSite>::GetHash(storage_key->GetTopLevelSite()),
       static_cast<unsigned>(storage_key->GetAncestorChainBit()),
 #if ARCH_CPU_32_BITS
       nonce_hash,
diff --git a/third_party/blink/renderer/platform/weborigin/kurl.h b/third_party/blink/renderer/platform/weborigin/kurl.h
index 68a4ddf..7b9dd9d 100644
--- a/third_party/blink/renderer/platform/weborigin/kurl.h
+++ b/third_party/blink/renderer/platform/weborigin/kurl.h
@@ -72,8 +72,6 @@
 
 namespace blink {
 
-struct KURLHash;
-
 class PLATFORM_EXPORT KURL {
   USING_FAST_MALLOC(KURL);
 
@@ -312,11 +310,9 @@
 
 namespace WTF {
 
-// KURLHash is the default hash for String
+// Defined in kurl_hash.h.
 template <>
-struct DefaultHash<blink::KURL> {
-  typedef blink::KURLHash Hash;
-};
+struct DefaultHash<blink::KURL>;
 
 template <>
 struct CrossThreadCopier<blink::KURL>
diff --git a/third_party/blink/renderer/platform/weborigin/kurl_hash.h b/third_party/blink/renderer/platform/weborigin/kurl_hash.h
index fde2401..4c9a0b1 100644
--- a/third_party/blink/renderer/platform/weborigin/kurl_hash.h
+++ b/third_party/blink/renderer/platform/weborigin/kurl_hash.h
@@ -55,6 +55,9 @@
 namespace WTF {
 
 template <>
+struct DefaultHash<blink::KURL> : blink::KURLHash {};
+
+template <>
 struct HashTraits<blink::KURL> : SimpleClassHashTraits<blink::KURL> {
   static bool IsDeletedValue(const blink::KURL& value) {
     return HashTraits<String>::IsDeletedValue(value.GetString());
diff --git a/third_party/blink/renderer/platform/weborigin/scheme_registry.h b/third_party/blink/renderer/platform/weborigin/scheme_registry.h
index fa56039a..c00823e9 100644
--- a/third_party/blink/renderer/platform/weborigin/scheme_registry.h
+++ b/third_party/blink/renderer/platform/weborigin/scheme_registry.h
@@ -41,7 +41,7 @@
 template <typename Mapped, typename MappedTraits>
 using URLSchemesMap = HashMap<String,
                               Mapped,
-                              DefaultHash<String>::Hash,
+                              DefaultHash<String>,
                               HashTraits<String>,
                               MappedTraits>;
 
diff --git a/third_party/blink/renderer/platform/widget/compositing/render_frame_metadata_observer_impl.cc b/third_party/blink/renderer/platform/widget/compositing/render_frame_metadata_observer_impl.cc
index e0d7603..c14fe769 100644
--- a/third_party/blink/renderer/platform/widget/compositing/render_frame_metadata_observer_impl.cc
+++ b/third_party/blink/renderer/platform/widget/compositing/render_frame_metadata_observer_impl.cc
@@ -28,7 +28,7 @@
 
 RenderFrameMetadataObserverImpl::~RenderFrameMetadataObserverImpl() {}
 
-void RenderFrameMetadataObserverImpl::BindToCurrentThread() {
+void RenderFrameMetadataObserverImpl::BindToCurrentSequence() {
   DCHECK(receiver_.is_valid());
   render_frame_metadata_observer_receiver_.Bind(std::move(receiver_));
   render_frame_metadata_observer_client_.Bind(std::move(client_remote_));
diff --git a/third_party/blink/renderer/platform/widget/compositing/render_frame_metadata_observer_impl.h b/third_party/blink/renderer/platform/widget/compositing/render_frame_metadata_observer_impl.h
index bcd2f288..cd414fa 100644
--- a/third_party/blink/renderer/platform/widget/compositing/render_frame_metadata_observer_impl.h
+++ b/third_party/blink/renderer/platform/widget/compositing/render_frame_metadata_observer_impl.h
@@ -22,7 +22,7 @@
 // cc::mojom::RenderFrameMetadataObserverClient, which is expected to be in the
 // browser process, of the metadata associated with the frame.
 //
-// BindToCurrentThread should be called from the Compositor thread so that the
+// BindToCurrentSequence should be called from the Compositor thread so that the
 // Mojo pipe is properly bound.
 //
 // Subsequent usage should only be from the Compositor thread.
@@ -38,7 +38,7 @@
   ~RenderFrameMetadataObserverImpl() override;
 
   // cc::RenderFrameMetadataObserver:
-  void BindToCurrentThread() override;
+  void BindToCurrentSequence() override;
   void OnRenderFrameSubmission(
       const cc::RenderFrameMetadata& render_frame_metadata,
       viz::CompositorFrameMetadata* compositor_frame_metadata,
@@ -78,7 +78,7 @@
   uint32_t last_frame_token_ = 0;
   absl::optional<cc::RenderFrameMetadata> last_render_frame_metadata_;
 
-  // These are destroyed when BindToCurrentThread() is called.
+  // These are destroyed when BindToCurrentSequence() is called.
   mojo::PendingReceiver<cc::mojom::blink::RenderFrameMetadataObserver>
       receiver_;
   mojo::PendingRemote<cc::mojom::blink::RenderFrameMetadataObserverClient>
diff --git a/third_party/blink/renderer/platform/widget/compositing/render_frame_metadata_observer_impl_unittest.cc b/third_party/blink/renderer/platform/widget/compositing/render_frame_metadata_observer_impl_unittest.cc
index e1e0207..0b3f25d 100644
--- a/third_party/blink/renderer/platform/widget/compositing/render_frame_metadata_observer_impl_unittest.cc
+++ b/third_party/blink/renderer/platform/widget/compositing/render_frame_metadata_observer_impl_unittest.cc
@@ -86,7 +86,7 @@
         std::move(observer_remote));
     observer_impl_ = std::make_unique<RenderFrameMetadataObserverImpl>(
         std::move(receiver), std::move(client_remote));
-    observer_impl_->BindToCurrentThread();
+    observer_impl_->BindToCurrentSequence();
   }
 
   void TearDown() override {
diff --git a/third_party/blink/renderer/platform/wtf/hash_counted_set.h b/third_party/blink/renderer/platform/wtf/hash_counted_set.h
index 1ece827..a35b13f 100644
--- a/third_party/blink/renderer/platform/wtf/hash_counted_set.h
+++ b/third_party/blink/renderer/platform/wtf/hash_counted_set.h
@@ -32,7 +32,7 @@
 // the set. The iterators have fields ->key and ->value that return the set
 // members and their counts, respectively.
 template <typename Value,
-          typename HashFunctions = typename DefaultHash<Value>::Hash,
+          typename HashFunctions = DefaultHash<Value>,
           typename Traits = HashTraits<Value>,
           typename Allocator = PartitionAllocator>
 class HashCountedSet {
diff --git a/third_party/blink/renderer/platform/wtf/hash_functions.h b/third_party/blink/renderer/platform/wtf/hash_functions.h
index 2be5479..ffbaab84 100644
--- a/third_party/blink/renderer/platform/wtf/hash_functions.h
+++ b/third_party/blink/renderer/platform/wtf/hash_functions.h
@@ -202,9 +202,7 @@
 struct DefaultHashImpl;
 
 template <typename T>
-struct DefaultHashImpl<T, true> {
-  using Hash = IntHash<T>;
-};
+struct DefaultHashImpl<T, true> : IntHash<T> {};
 
 // Canonical implementation of DefaultHash.
 template <typename T>
@@ -214,27 +212,17 @@
 
 // Specializations of DefaultHash follow.
 template <>
-struct DefaultHash<float> {
-  using Hash = FloatHash<float>;
-};
+struct DefaultHash<float> : FloatHash<float> {};
 template <>
-struct DefaultHash<double> {
-  using Hash = FloatHash<double>;
-};
+struct DefaultHash<double> : FloatHash<double> {};
 
 // Specializations for pointer types.
 template <typename T>
-struct DefaultHash<T*> {
-  using Hash = PtrHash<T>;
-};
+struct DefaultHash<T*> : PtrHash<T> {};
 template <typename T>
-struct DefaultHash<scoped_refptr<T>> {
-  using Hash = RefPtrHash<T>;
-};
+struct DefaultHash<scoped_refptr<T>> : RefPtrHash<T> {};
 template <typename T>
-struct DefaultHash<std::unique_ptr<T>> {
-  using Hash = UniquePtrHash<T>;
-};
+struct DefaultHash<std::unique_ptr<T>> : UniquePtrHash<T> {};
 
 // Specializations for pairs.
 
@@ -242,16 +230,16 @@
 template <typename T, typename U, bool areBothIntegral>
 struct PairHashImpl {
   static unsigned GetHash(const std::pair<T, U>& p) {
-    return HashInts(DefaultHash<T>::Hash::GetHash(p.first),
-                    DefaultHash<U>::Hash::GetHash(p.second));
+    return HashInts(DefaultHash<T>::GetHash(p.first),
+                    DefaultHash<U>::GetHash(p.second));
   }
   static bool Equal(const std::pair<T, U>& a, const std::pair<T, U>& b) {
-    return DefaultHash<T>::Hash::Equal(a.first, b.first) &&
-           DefaultHash<U>::Hash::Equal(a.second, b.second);
+    return DefaultHash<T>::Equal(a.first, b.first) &&
+           DefaultHash<U>::Equal(a.second, b.second);
   }
   static const bool safe_to_compare_to_empty_or_deleted =
-      DefaultHash<T>::Hash::safe_to_compare_to_empty_or_deleted &&
-      DefaultHash<U>::Hash::safe_to_compare_to_empty_or_deleted;
+      DefaultHash<T>::safe_to_compare_to_empty_or_deleted &&
+      DefaultHash<U>::safe_to_compare_to_empty_or_deleted;
 };
 
 // Special version for pairs of integrals:
@@ -276,9 +264,7 @@
                    std::is_integral<T>::value && std::is_integral<U>::value> {};
 
 template <typename T, typename U>
-struct DefaultHash<std::pair<T, U>> {
-  using Hash = PairHash<T, U>;
-};
+struct DefaultHash<std::pair<T, U>> : PairHash<T, U> {};
 
 // Wrapper for integral type to extend to have 0 and max keys.
 template <typename T>
@@ -329,9 +315,7 @@
 };
 
 template <typename T>
-struct DefaultHash<IntegralWithAllKeys<T>> {
-  using Hash = IntegralWithAllKeysHash<T>;
-};
+struct DefaultHash<IntegralWithAllKeys<T>> : IntegralWithAllKeysHash<T> {};
 
 }  // namespace WTF
 
diff --git a/third_party/blink/renderer/platform/wtf/hash_map.h b/third_party/blink/renderer/platform/wtf/hash_map.h
index f2b4c790..47b5d51c 100644
--- a/third_party/blink/renderer/platform/wtf/hash_map.h
+++ b/third_party/blink/renderer/platform/wtf/hash_map.h
@@ -60,7 +60,7 @@
 // can be lifted if you supply custom key traits.
 template <typename KeyArg,
           typename MappedArg,
-          typename HashArg = typename DefaultHash<KeyArg>::Hash,
+          typename HashArg = DefaultHash<KeyArg>,
           typename KeyTraitsArg = HashTraits<KeyArg>,
           typename MappedTraitsArg = HashTraits<MappedArg>,
           typename Allocator = PartitionAllocator>
diff --git a/third_party/blink/renderer/platform/wtf/hash_map_test.cc b/third_party/blink/renderer/platform/wtf/hash_map_test.cc
index 7d8f844f..6011b5b8 100644
--- a/third_party/blink/renderer/platform/wtf/hash_map_test.cc
+++ b/third_party/blink/renderer/platform/wtf/hash_map_test.cc
@@ -92,10 +92,10 @@
 };
 
 using DoubleHashMap =
-    HashMap<double, int64_t, DefaultHash<double>::Hash, TestDoubleHashTraits>;
+    HashMap<double, int64_t, DefaultHash<double>, TestDoubleHashTraits>;
 
 int BucketForKey(double key) {
-  return DefaultHash<double>::Hash::GetHash(key) &
+  return DefaultHash<double>::GetHash(key) &
          (TestDoubleHashTraits::kMinimumTableSize - 1);
 }
 
@@ -627,16 +627,16 @@
 }
 
 TEST(HashMapTest, IsValidKey) {
-  static_assert(DefaultHash<int>::Hash::safe_to_compare_to_empty_or_deleted,
+  static_assert(DefaultHash<int>::safe_to_compare_to_empty_or_deleted,
                 "type should be comparable to empty or deleted");
-  static_assert(DefaultHash<int*>::Hash::safe_to_compare_to_empty_or_deleted,
-                "type should be comparable to empty or deleted");
-  static_assert(DefaultHash<scoped_refptr<DummyRefCounted>>::Hash::
-                    safe_to_compare_to_empty_or_deleted,
+  static_assert(DefaultHash<int*>::safe_to_compare_to_empty_or_deleted,
                 "type should be comparable to empty or deleted");
   static_assert(
-      !DefaultHash<AtomicString>::Hash::safe_to_compare_to_empty_or_deleted,
-      "type should not be comparable to empty or deleted");
+      DefaultHash<
+          scoped_refptr<DummyRefCounted>>::safe_to_compare_to_empty_or_deleted,
+      "type should be comparable to empty or deleted");
+  static_assert(!DefaultHash<AtomicString>::safe_to_compare_to_empty_or_deleted,
+                "type should not be comparable to empty or deleted");
 
   EXPECT_FALSE((HashMap<int, int>::IsValidKey(0)));
   EXPECT_FALSE((HashMap<int, int>::IsValidKey(-1)));
diff --git a/third_party/blink/renderer/platform/wtf/hash_set.h b/third_party/blink/renderer/platform/wtf/hash_set.h
index c343f43..e15288b 100644
--- a/third_party/blink/renderer/platform/wtf/hash_set.h
+++ b/third_party/blink/renderer/platform/wtf/hash_set.h
@@ -38,7 +38,7 @@
 // allowed; for integer keys 0 or -1 can't be used as a key. This restriction
 // can be lifted if you supply custom key traits.
 template <typename ValueArg,
-          typename HashArg = typename DefaultHash<ValueArg>::Hash,
+          typename HashArg = DefaultHash<ValueArg>,
           typename TraitsArg = HashTraits<ValueArg>,
           typename Allocator = PartitionAllocator>
 class HashSet {
diff --git a/third_party/blink/renderer/platform/wtf/linked_hash_set.h b/third_party/blink/renderer/platform/wtf/linked_hash_set.h
index a0f7121..32c86f94 100644
--- a/third_party/blink/renderer/platform/wtf/linked_hash_set.h
+++ b/third_party/blink/renderer/platform/wtf/linked_hash_set.h
@@ -50,7 +50,7 @@
 // Note: empty/deleted values as defined in HashTraits are not allowed.
 template <typename ValueArg,
           typename TraitsArg = HashTraits<ValueArg>,
-          typename HashArg = typename DefaultHash<ValueArg>::Hash,
+          typename HashArg = DefaultHash<ValueArg>,
           typename Allocator = PartitionAllocator>
 class LinkedHashSet {
   USE_ALLOCATOR(LinkedHashSet, Allocator);
diff --git a/third_party/blink/renderer/platform/wtf/linked_hash_set_test.cc b/third_party/blink/renderer/platform/wtf/linked_hash_set_test.cc
index ce38c377..438ab12 100644
--- a/third_party/blink/renderer/platform/wtf/linked_hash_set_test.cc
+++ b/third_party/blink/renderer/platform/wtf/linked_hash_set_test.cc
@@ -666,13 +666,11 @@
 
 template <>
 struct DefaultHash<EmptyString> {
-  struct Hash {
-    static unsigned GetHash(const EmptyString&) { return 0; }
-    static bool Equal(const EmptyString& value1, const EmptyString& value2) {
-      return value1 == value2;
-    }
-    static const bool safe_to_compare_to_empty_or_deleted = true;
-  };
+  static unsigned GetHash(const EmptyString&) { return 0; }
+  static bool Equal(const EmptyString& value1, const EmptyString& value2) {
+    return value1 == value2;
+  }
+  static const bool safe_to_compare_to_empty_or_deleted = true;
 };
 
 TEST(LinkedHashSetTest, Swap) {
diff --git a/third_party/blink/renderer/platform/wtf/text/atomic_string.h b/third_party/blink/renderer/platform/wtf/text/atomic_string.h
index d10b067..45a5a3b 100644
--- a/third_party/blink/renderer/platform/wtf/text/atomic_string.h
+++ b/third_party/blink/renderer/platform/wtf/text/atomic_string.h
@@ -38,8 +38,6 @@
 
 namespace WTF {
 
-struct AtomicStringHash;
-
 // An AtomicString instance represents a string, and multiple AtomicString
 // instances can share their string storage if the strings are
 // identical. Comparing two AtomicString instances is much faster than comparing
@@ -285,13 +283,11 @@
 WTF_EXPORT extern const AtomicString& g_http_atom;
 WTF_EXPORT extern const AtomicString& g_https_atom;
 
-// AtomicStringHash is the default hash for AtomicString
 template <typename T>
 struct DefaultHash;
+// Defined in atomic_string_hash.h.
 template <>
-struct DefaultHash<AtomicString> {
-  typedef AtomicStringHash Hash;
-};
+struct DefaultHash<AtomicString>;
 
 // Pretty printer for gtest and base/logging.*.  It prepends and appends
 // double-quotes, and escapes characters other than ASCII printables.
diff --git a/third_party/blink/renderer/platform/wtf/text/atomic_string_hash.h b/third_party/blink/renderer/platform/wtf/text/atomic_string_hash.h
index 53bc41569..6266304 100644
--- a/third_party/blink/renderer/platform/wtf/text/atomic_string_hash.h
+++ b/third_party/blink/renderer/platform/wtf/text/atomic_string_hash.h
@@ -49,6 +49,9 @@
 
 // AtomicStringHash is the default hash for AtomicString
 template <>
+struct DefaultHash<AtomicString> : AtomicStringHash {};
+
+template <>
 struct HashTraits<AtomicString> : SimpleClassHashTraits<AtomicString> {
   // Unlike other types, we can return a const reference for AtomicString's
   // empty value (g_null_atom).
diff --git a/third_party/blink/renderer/platform/wtf/text/string_hash.h b/third_party/blink/renderer/platform/wtf/text/string_hash.h
index ff1c5f57..e55bd90 100644
--- a/third_party/blink/renderer/platform/wtf/text/string_hash.h
+++ b/third_party/blink/renderer/platform/wtf/text/string_hash.h
@@ -25,8 +25,8 @@
 #include "base/check_op.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/hash_traits.h"
-#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_hasher.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
 namespace WTF {
 
@@ -78,6 +78,15 @@
   static unsigned GetHash(unsigned key) { return key; }
 };
 
+// StringHash is the default hash for String, StringImpl* and
+// scopoed_refptr<StringImpl>.
+template <>
+struct DefaultHash<String> : StringHash {};
+template <>
+struct DefaultHash<StringImpl*> : StringHash {};
+template <>
+struct DefaultHash<scoped_refptr<StringImpl>> : StringHash {};
+
 }  // namespace WTF
 
 namespace std {
diff --git a/third_party/blink/renderer/platform/wtf/text/string_impl.h b/third_party/blink/renderer/platform/wtf/text/string_impl.h
index da65ab2..9030e7a3 100644
--- a/third_party/blink/renderer/platform/wtf/text/string_impl.h
+++ b/third_party/blink/renderer/platform/wtf/text/string_impl.h
@@ -947,19 +947,13 @@
     result.Prepend(Characters16() + start, number_of_characters_to_copy);
 }
 
-struct StringHash;
-
-// StringHash is the default hash for StringImpl* and scoped_refptr<StringImpl>
 template <typename T>
 struct DefaultHash;
+// Defined in string_hash.h.
 template <>
-struct DefaultHash<StringImpl*> {
-  typedef StringHash Hash;
-};
+struct DefaultHash<StringImpl*>;
 template <>
-struct DefaultHash<scoped_refptr<StringImpl>> {
-  typedef StringHash Hash;
-};
+struct DefaultHash<scoped_refptr<StringImpl>>;
 
 }  // namespace WTF
 
diff --git a/third_party/blink/renderer/platform/wtf/text/wtf_string.h b/third_party/blink/renderer/platform/wtf/text/wtf_string.h
index aeadc11b..f24044f 100644
--- a/third_party/blink/renderer/platform/wtf/text/wtf_string.h
+++ b/third_party/blink/renderer/platform/wtf/text/wtf_string.h
@@ -45,8 +45,6 @@
 
 namespace WTF {
 
-struct StringHash;
-
 #define DISPATCH_CASE_OP(caseSensitivity, op, args)     \
   ((caseSensitivity == kTextCaseSensitive)              \
        ? op args                                        \
@@ -666,13 +664,11 @@
   impl_->PrependTo(result, position, length);
 }
 
-// StringHash is the default hash for String
 template <typename T>
 struct DefaultHash;
+// Defined in string_hash.h.
 template <>
-struct DefaultHash<String> {
-  typedef StringHash Hash;
-};
+struct DefaultHash<String>;
 
 // Shared global empty string.
 WTF_EXPORT extern const String& g_empty_string;
diff --git a/third_party/blink/renderer/platform/wtf/wtf_test_helper.h b/third_party/blink/renderer/platform/wtf/wtf_test_helper.h
index 79f1577..df143432 100644
--- a/third_party/blink/renderer/platform/wtf/wtf_test_helper.h
+++ b/third_party/blink/renderer/platform/wtf/wtf_test_helper.h
@@ -105,22 +105,20 @@
 
 struct MoveOnlyHash {
   static unsigned GetHash(const MoveOnlyHashValue& value) {
-    return DefaultHash<int>::Hash::GetHash(value.Value());
+    return DefaultHash<int>::GetHash(value.Value());
   }
   static bool Equal(const MoveOnlyHashValue& left,
                     const MoveOnlyHashValue& right) {
-    return DefaultHash<int>::Hash::Equal(left.Value(), right.Value());
+    return DefaultHash<int>::Equal(left.Value(), right.Value());
   }
   static const bool safe_to_compare_to_empty_or_deleted = true;
 };
 
 template <>
-struct HashTraits<MoveOnlyHashValue> : public MoveOnlyHashTraits {};
+struct HashTraits<MoveOnlyHashValue> : MoveOnlyHashTraits {};
 
 template <>
-struct DefaultHash<MoveOnlyHashValue> {
-  using Hash = MoveOnlyHash;
-};
+struct DefaultHash<MoveOnlyHashValue> : MoveOnlyHash {};
 
 class CountCopy final {
  public:
@@ -169,12 +167,10 @@
 };
 
 template <>
-struct HashTraits<CountCopy> : public CountCopyHashTraits {};
+struct HashTraits<CountCopy> : CountCopyHashTraits {};
 
 template <>
-struct DefaultHash<CountCopy> {
-  using Hash = CountCopyHash;
-};
+struct DefaultHash<CountCopy> : CountCopyHash {};
 
 template <typename T>
 class ValueInstanceCount final {
@@ -247,9 +243,7 @@
     : public ValueInstanceCountHashTraits<T> {};
 
 template <typename T>
-struct DefaultHash<ValueInstanceCount<T>> {
-  using Hash = ValueInstanceCountHash<T>;
-};
+struct DefaultHash<ValueInstanceCount<T>> : public ValueInstanceCountHash<T> {};
 
 class DummyRefCounted : public RefCounted<DummyRefCounted> {
  public:
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 8be9236d..2f49c12 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -7162,7 +7162,7 @@
 # Disable PendingBeaconAPI related internal tests tentatively until it is
 # fully launched.
 # The ones defined in VirtualTestSuites are run instead.
-crbug.com/1293679 wpt_internal/pending_beacon/* [ Skip ]
+crbug.com/1293679 wpt_internal/unload-beacon/* [ Skip ]
 
 # TODO(crbug.com/1367103): Re-enable this test
 external/wpt/css/css-values/calc-in-media-queries-with-mixed-units.html [ Skip ]
@@ -7280,3 +7280,6 @@
 crbug.com/1374264 [ Mac ] external/wpt/screen-capture/permissions-policy-video.https.sub.html [ Failure ]
 
 crbug.com/1372181 external/wpt/scroll-animations/css/scroll-timeline-default-iframe-print.html [ Failure ]
+
+# Sheriff 2022-10-04
+crbug.com/1145491 [ Mac ] virtual/controls-refresh-hc/fast/forms/color-scheme/media/video-overlay-menu.html [ Skip ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites
index 014f5ddba..f120845 100644
--- a/third_party/blink/web_tests/VirtualTestSuites
+++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -1252,7 +1252,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": [
       "external/wpt/unload-beacon",
-      "wpt_internal/pending_beacon"
+      "wpt_internal/unload-beacon"
     ],
     "args": [
       "--enable-features=PendingBeaconAPI:requires_origin_trial/false"
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/OWNERS b/third_party/blink/web_tests/external/wpt/content-security-policy/OWNERS
index 06ebdda..1245fcd 100644
--- a/third_party/blink/web_tests/external/wpt/content-security-policy/OWNERS
+++ b/third_party/blink/web_tests/external/wpt/content-security-policy/OWNERS
@@ -1,3 +1,2 @@
+antoniosartori@chromium.org
 arthursonzogni@chromium.org
-mkwst@chromium.org
-andypaicu@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/cookies/OWNERS b/third_party/blink/web_tests/external/wpt/cookies/OWNERS
index 3f84563..24eebbd 100644
--- a/third_party/blink/web_tests/external/wpt/cookies/OWNERS
+++ b/third_party/blink/web_tests/external/wpt/cookies/OWNERS
@@ -1 +1 @@
-mkwst@chromium.org
+bingler@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/fixedpos-with-link-with-inline-child-print-ref.html b/third_party/blink/web_tests/external/wpt/css/css-break/fixedpos-with-link-with-inline-child-print-ref.html
new file mode 100644
index 0000000..f12d31a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/fixedpos-with-link-with-inline-child-print-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<style>
+  body { margin: 0; }
+</style>
+<div>
+  <a href="/">Link <span>should be seen</span> on both pages.</a>
+</div>
+<div style="break-before:page;">
+  <a href="/">Link <span>should be seen</span> on both pages.</a>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/fixedpos-with-link-with-inline-child-print.html b/third_party/blink/web_tests/external/wpt/css/css-break/fixedpos-with-link-with-inline-child-print.html
new file mode 100644
index 0000000..694e537
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/fixedpos-with-link-with-inline-child-print.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1373172">
+<link rel="match" href="fixedpos-with-link-with-inline-child-print-ref.html">
+<style>
+  body { margin: 0; }
+</style>
+<div style="position:fixed;">
+  <a href="/">Link <span>should be seen</span> on both pages.</a>
+</div>
+<div style="break-before:page; height:10px;"></div>
+<div style="break-before:page; height:10px;"></div>
diff --git a/third_party/blink/web_tests/external/wpt/fetch/OWNERS b/third_party/blink/web_tests/external/wpt/fetch/OWNERS
index c48f060..a1e1bba 100644
--- a/third_party/blink/web_tests/external/wpt/fetch/OWNERS
+++ b/third_party/blink/web_tests/external/wpt/fetch/OWNERS
@@ -1,2 +1 @@
-mkwst@chromium.org
 japhet@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/fetch/private-network-access/iframe.tentative.window.js b/third_party/blink/web_tests/external/wpt/fetch/private-network-access/iframe.tentative.window.js
new file mode 100644
index 0000000..e91874d9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fetch/private-network-access/iframe.tentative.window.js
@@ -0,0 +1,98 @@
+// META: script=/common/utils.js
+// META: script=resources/support.sub.js
+// META: timeout=long
+//
+// Spec: https://wicg.github.io/private-network-access/#integration-fetch
+//
+// These tests verify that non-secure contexts cannot navigate iframes to
+// less-public address spaces, and can navigate them otherwise.
+//
+// This file covers only those tests that must execute in a non secure context.
+// Other tests are defined in: iframe.https.window.js
+
+setup(() => {
+  // Making sure we are in a non secure context, as expected.
+  assert_false(window.isSecureContext);
+});
+
+promise_test(t => iframeTest(t, {
+  source: { server: Server.HTTP_LOCAL },
+  target: { server: Server.HTTP_LOCAL },
+  expected: IframeTestResult.SUCCESS,
+}), "local to local: no preflight required.");
+
+promise_test(t => iframeTest(t, {
+  source: { server: Server.HTTP_LOCAL },
+  target: { server: Server.HTTP_PRIVATE },
+  expected: IframeTestResult.SUCCESS,
+}), "local to private: no preflight required.");
+
+promise_test(t => iframeTest(t, {
+  source: { server: Server.HTTP_LOCAL },
+  target: { server: Server.HTTP_PUBLIC },
+  expected: IframeTestResult.SUCCESS,
+}), "local to public: no preflight required.");
+
+promise_test(t => iframeTest(t, {
+  source: { server: Server.HTTP_PRIVATE },
+  target: { server: Server.HTTP_LOCAL },
+  expected: IframeTestResult.FAILURE,
+}), "private to local: failure.");
+
+promise_test(t => iframeTest(t, {
+  source: { server: Server.HTTP_PRIVATE },
+  target: { server: Server.HTTP_PRIVATE },
+  expected: IframeTestResult.SUCCESS,
+}), "private to private: no preflight required.");
+
+promise_test(t => iframeTest(t, {
+  source: { server: Server.HTTP_PRIVATE },
+  target: { server: Server.HTTP_PUBLIC },
+  expected: IframeTestResult.SUCCESS,
+}), "private to public: no preflight required.");
+
+promise_test(t => iframeTest(t, {
+  source: { server: Server.HTTP_PUBLIC },
+  target: { server: Server.HTTP_LOCAL },
+  expected: IframeTestResult.FAILURE,
+}), "public to local: failure.");
+
+
+promise_test(t => iframeTest(t, {
+  source: { server: Server.HTTP_PUBLIC },
+  target: { server: Server.HTTP_PRIVATE },
+  expected: IframeTestResult.FAILURE,
+}), "public to private: failure.");
+
+promise_test(t => iframeTest(t, {
+  source: { server: Server.HTTP_PUBLIC },
+  target: { server: Server.HTTP_PUBLIC },
+  expected: IframeTestResult.SUCCESS,
+}), "public to public: no preflight required.");
+
+promise_test(t => iframeTest(t, {
+  source: {
+    server: Server.HTTP_LOCAL,
+    treatAsPublic: true,
+  },
+  target: { server: Server.HTTP_LOCAL },
+  expected: IframeTestResult.FAILURE,
+}), "treat-as-public-address to local: failure.");
+
+promise_test(t => iframeTest(t, {
+  source: {
+    server: Server.HTTP_LOCAL,
+    treatAsPublic: true,
+  },
+  target: { server: Server.HTTP_PRIVATE },
+  expected: IframeTestResult.FAILURE,
+}), "treat-as-public-address to private: failure.");
+
+promise_test(t => iframeTest(t, {
+  source: {
+    server: Server.HTTP_LOCAL,
+    treatAsPublic: true,
+  },
+  target: { server: Server.HTTP_PUBLIC },
+  expected: IframeTestResult.SUCCESS,
+}), "treat-as-public-address to public: no preflight required.");
diff --git a/third_party/blink/web_tests/external/wpt/fetch/private-network-access/resources/iframed.html b/third_party/blink/web_tests/external/wpt/fetch/private-network-access/resources/iframed.html
new file mode 100644
index 0000000..694884f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fetch/private-network-access/resources/iframed.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Iframed</title>
+<script>
+  top.postMessage("loaded", "*");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/fetch/private-network-access/resources/iframer.html b/third_party/blink/web_tests/external/wpt/fetch/private-network-access/resources/iframer.html
new file mode 100644
index 0000000..304cc54
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fetch/private-network-access/resources/iframer.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Iframer</title>
+<body></body>
+<script>
+  const child = document.createElement("iframe");
+  child.src = new URL(window.location).searchParams.get("url");
+  document.body.appendChild(child);
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/fetch/private-network-access/resources/support.sub.js b/third_party/blink/web_tests/external/wpt/fetch/private-network-access/resources/support.sub.js
index 3bf9ed00..afa82d3 100644
--- a/third_party/blink/web_tests/external/wpt/fetch/private-network-access/resources/support.sub.js
+++ b/third_party/blink/web_tests/external/wpt/fetch/private-network-access/resources/support.sub.js
@@ -26,12 +26,33 @@
 
 // Register an event listener that will resolve this promise when this
 // window receives a message posted to it.
-function futureMessage() {
+//
+// `options` has the following shape:
+//
+//  {
+//    // If specified, this function waits for the first message from the given
+//    // source only, ignoring other messages.
+//    source,
+//  }
+//
+function futureMessage(options) {
   return new Promise(resolve => {
-      window.addEventListener("message", e => resolve(e.data));
+    window.addEventListener("message", (e) => {
+      if (options?.source && options.source !== e.source) {
+        return;
+      }
+
+      resolve(e.data);
+    });
   });
 };
 
+async function postMessageAndAwaitReply(target, message) {
+  const reply = futureMessage({ source: target });
+  target.postMessage(message, "*");
+  return await reply;
+}
+
 const Server = {
   HTTP_LOCAL: {
     port: {{ports[http][0]}},
@@ -315,6 +336,35 @@
   assert_equals(body, expected.body, "response body");
 }
 
+const IframeTestResult = {
+  SUCCESS: "loaded",
+  FAILURE: "timeout",
+};
+
+async function iframeTest(t, { source, target, expected }) {
+  const targetUrl = preflightUrl(target);
+  targetUrl.searchParams.set("file", "iframed.html");
+
+  const sourceUrl =
+      resolveUrl("resources/iframer.html", sourceResolveOptions(source));
+  sourceUrl.searchParams.set("url", targetUrl);
+
+  const messagePromise = futureMessage();
+  const iframe = await appendIframe(t, document, sourceUrl);
+
+  // The grandchild frame posts a message iff it loads successfully.
+  // There exists no interoperable way to check whether an iframe failed to
+  // load, so we use a timeout. See: https://github.com/whatwg/html/issues/125
+  const result = await Promise.race([
+      messagePromise,
+      new Promise((resolve) => {
+        t.step_timeout(() => resolve("timeout"), 500 /* ms */);
+      }),
+  ]);
+
+  assert_equals(result, expected);
+}
+
 const WebsocketTestResult = {
   SUCCESS: "open",
 
diff --git a/third_party/blink/web_tests/external/wpt/fs/FileSystemFileHandle-move.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/fs/FileSystemFileHandle-move.https.any-expected.txt
index 407d9d04..421ba84 100644
--- a/third_party/blink/web_tests/external/wpt/fs/FileSystemFileHandle-move.https.any-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/fs/FileSystemFileHandle-move.https.any-expected.txt
@@ -12,10 +12,9 @@
 PASS move(dir, name) to rename a file
 PASS move(dir, name) to rename a file the same name
 PASS move(dir) to move a file to a new directory
-PASS move(dir, "") to move a file to a new directory
+PASS move(dir, "") to move a file to a new directory fails
 PASS move(dir, name) to move a file to a new directory
 PASS move(dir) can be called multiple times
-PASS move(dir, "") can be called multiple times
 PASS move(dir, name) can be called multiple times
 PASS move(dir, name) with a name with invalid characters should fail
 PASS move(dir) while the file has an open writable fails
diff --git a/third_party/blink/web_tests/external/wpt/fs/FileSystemFileHandle-move.https.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/fs/FileSystemFileHandle-move.https.any.worker-expected.txt
index 407d9d04..421ba84 100644
--- a/third_party/blink/web_tests/external/wpt/fs/FileSystemFileHandle-move.https.any.worker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/fs/FileSystemFileHandle-move.https.any.worker-expected.txt
@@ -12,10 +12,9 @@
 PASS move(dir, name) to rename a file
 PASS move(dir, name) to rename a file the same name
 PASS move(dir) to move a file to a new directory
-PASS move(dir, "") to move a file to a new directory
+PASS move(dir, "") to move a file to a new directory fails
 PASS move(dir, name) to move a file to a new directory
 PASS move(dir) can be called multiple times
-PASS move(dir, "") can be called multiple times
 PASS move(dir, name) can be called multiple times
 PASS move(dir, name) with a name with invalid characters should fail
 PASS move(dir) while the file has an open writable fails
diff --git a/third_party/blink/web_tests/external/wpt/fs/script-tests/FileSystemFileHandle-move.js b/third_party/blink/web_tests/external/wpt/fs/script-tests/FileSystemFileHandle-move.js
index c914bd82..a65251e 100644
--- a/third_party/blink/web_tests/external/wpt/fs/script-tests/FileSystemFileHandle-move.js
+++ b/third_party/blink/web_tests/external/wpt/fs/script-tests/FileSystemFileHandle-move.js
@@ -138,15 +138,15 @@
   const dir_src = await root.getDirectoryHandle('dir-src', {create: true});
   const dir_dest = await root.getDirectoryHandle('dir-dest', {create: true});
   const file = await createFileWithContents(t, 'file', 'abc', dir_src);
-  await file.move(dir_dest, '');
+  await promise_rejects_js(t, TypeError, file.move(dir_dest, ''));
 
   assert_array_equals(
       await getSortedDirectoryEntries(root), ['dir-dest/', 'dir-src/']);
-  assert_array_equals(await getSortedDirectoryEntries(dir_src), []);
-  assert_array_equals(await getSortedDirectoryEntries(dir_dest), ['file']);
+  assert_array_equals(await getSortedDirectoryEntries(dir_src), ['file']);
+  assert_array_equals(await getSortedDirectoryEntries(dir_dest), []);
   assert_equals(await getFileContents(file), 'abc');
   assert_equals(await getFileSize(file), 3);
-}, 'move(dir, "") to move a file to a new directory');
+}, 'move(dir, "") to move a file to a new directory fails');
 
 directory_test(async (t, root) => {
   const dir_src = await root.getDirectoryHandle('dir-src', {create: true});
@@ -196,33 +196,6 @@
   const dir2 = await root.getDirectoryHandle('dir2', {create: true});
   const handle = await createFileWithContents(t, 'file', 'foo', root);
 
-  await handle.move(dir1, "");
-  assert_array_equals(
-      await getSortedDirectoryEntries(root), ['dir1/', 'dir2/']);
-  assert_array_equals(await getSortedDirectoryEntries(dir1), ['file']);
-  assert_array_equals(await getSortedDirectoryEntries(dir2), []);
-  assert_equals(await getFileContents(handle), 'foo');
-
-  await handle.move(dir2, "");
-  assert_array_equals(
-      await getSortedDirectoryEntries(root), ['dir1/', 'dir2/']);
-  assert_array_equals(await getSortedDirectoryEntries(dir1), []);
-  assert_array_equals(await getSortedDirectoryEntries(dir2), ['file']);
-  assert_equals(await getFileContents(handle), 'foo');
-
-  await handle.move(root, "");
-  assert_array_equals(
-      await getSortedDirectoryEntries(root), ['dir1/', 'dir2/', 'file']);
-  assert_array_equals(await getSortedDirectoryEntries(dir1), []);
-  assert_array_equals(await getSortedDirectoryEntries(dir2), []);
-  assert_equals(await getFileContents(handle), 'foo');
-}, 'move(dir, "") can be called multiple times');
-
-directory_test(async (t, root) => {
-  const dir1 = await root.getDirectoryHandle('dir1', {create: true});
-  const dir2 = await root.getDirectoryHandle('dir2', {create: true});
-  const handle = await createFileWithContents(t, 'file', 'foo', root);
-
   await handle.move(dir1, 'file-1');
   assert_array_equals(
       await getSortedDirectoryEntries(root), ['dir1/', 'dir2/']);
diff --git a/third_party/blink/web_tests/external/wpt/mixed-content/OWNERS b/third_party/blink/web_tests/external/wpt/mixed-content/OWNERS
index 3f84563..52ba67e 100644
--- a/third_party/blink/web_tests/external/wpt/mixed-content/OWNERS
+++ b/third_party/blink/web_tests/external/wpt/mixed-content/OWNERS
@@ -1 +1 @@
-mkwst@chromium.org
+carlosil@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/native-io/OWNERS b/third_party/blink/web_tests/external/wpt/native-io/OWNERS
index 565fba10..136f6d9 100644
--- a/third_party/blink/web_tests/external/wpt/native-io/OWNERS
+++ b/third_party/blink/web_tests/external/wpt/native-io/OWNERS
@@ -1,6 +1,2 @@
-# Primary
-mkwst@chromium.org
-
-# Secondary
 asully@chromium.org
 ayui@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/OWNERS b/third_party/blink/web_tests/external/wpt/trusted-types/OWNERS
index 3f84563..956a3a5 100644
--- a/third_party/blink/web_tests/external/wpt/trusted-types/OWNERS
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/OWNERS
@@ -1 +1 @@
-mkwst@chromium.org
+vogelheim@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/OWNERS b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/OWNERS
index 3f84563..52ba67e 100644
--- a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/OWNERS
+++ b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/OWNERS
@@ -1 +1 @@
-mkwst@chromium.org
+carlosil@chromium.org
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/follow-redirect-modify-headers-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/follow-redirect-modify-headers-expected.txt
index 5061c45..eabb5164d 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/follow-redirect-modify-headers-expected.txt
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/follow-redirect-modify-headers-expected.txt
@@ -1,7 +1,7 @@
 Tests that client can modify headers when continuing following a redirect response.
 Request headers after redirect
-HTTP_X_DEVTOOLSTEST1: This will remain as is
-HTTP_X_DEVTOOLSTEST2: <not set>
+HTTP_X_DEVTOOLSTEST1: <not set>
+HTTP_X_DEVTOOLSTEST2: 
 HTTP_X_DEVTOOLSTEST3: replaced with new value
 HTTP_X_DEVTOOLSTEST4: added
 
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/follow-redirect-modify-headers.js b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/follow-redirect-modify-headers.js
index a0fee61..ac0cdd82 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/follow-redirect-modify-headers.js
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/follow-redirect-modify-headers.js
@@ -5,8 +5,8 @@
   await dp.Fetch.enable({});
   const bodyPromise = session.evaluateAsync(`(function () {
     const headers = new Headers();
-    headers.append('X-DevToolsTest1', 'This will remain as is');
-    headers.append('X-DevToolsTest2', 'This will be removed');
+    headers.append('X-DevToolsTest1', 'This will be removed');
+    headers.append('X-DevToolsTest2', 'This will be set to empty');
     headers.append('X-DevToolsTest3', 'This will be replaced');
     headersToDump = [...headers.keys(), 'X-DevToolsTest4'].map(header => 'HTTP_' + header.toUpperCase().replace(/-/g,'_'));
     const redirect_url = '/inspector-protocol/network/resources/echo-headers.php?headers='
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/redirect-headers-override-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/redirect-headers-override-expected.txt
new file mode 100644
index 0000000..788d9e5
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/redirect-headers-override-expected.txt
@@ -0,0 +1,11 @@
+Tests overridden headers don't stick across redirects
+{
+    Cookie : bar=bazz
+    Referer : http://127.0.0.1:8000/inspector-protocol/resources/inspector-protocol-page.html
+    X-Devtools-Test : foo
+}
+HTTP_X_DEVTOOLS_TEST: <not set>
+HTTP_COOKIE: <not set>
+HTTP_REFERER: http://127.0.0.1:8000/inspector-protocol/resources/inspector-protocol-page.html
+
+
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/redirect-headers-override.js b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/redirect-headers-override.js
new file mode 100644
index 0000000..6993da4
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/redirect-headers-override.js
@@ -0,0 +1,28 @@
+(async function(testRunner) {
+  const {session, dp} = await testRunner.startBlank(
+      `Tests overridden headers don't stick across redirects`);
+
+  await dp.Fetch.enable();
+
+  // Note Referer still sticks due to implementation limitations.
+  const final_url = 'http://127.0.0.1:8000/inspector-protocol//network/resources/echo-headers.php?headers=HTTP_X_DEVTOOLS_TEST:HTTP_COOKIE:HTTP_REFERER';
+  const contentPromise = session.evaluateAsync(`
+    fetch('http://127.0.0.1:8000/inspector-protocol/fetch/resources/redirect.pl?${final_url}').then(r => r.text())
+  `);
+
+  const beforeRedirect = (await dp.Fetch.onceRequestPaused()).params;
+  dp.Fetch.continueRequest({
+    requestId: beforeRedirect.requestId,
+    headers: [
+      {name: 'X-Devtools-Test', value: 'foo'},
+      {name: 'Cookie', value: 'bar=bazz'}
+    ]
+  });
+  const afterRedirect = (await dp.Fetch.onceRequestPaused()).params;
+  testRunner.log(afterRedirect.request.headers);
+  dp.Fetch.continueRequest({
+    requestId: afterRedirect.requestId,
+  });
+  testRunner.log(await contentPromise);
+  testRunner.completeTest();
+})
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/redirect-headers-override2-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/redirect-headers-override2-expected.txt
new file mode 100644
index 0000000..994053b
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/redirect-headers-override2-expected.txt
@@ -0,0 +1,6 @@
+Tests overridden headers don't stick if redirected request is not intercepted following a redirect
+HTTP_X_DEVTOOLS_TEST: <not set>
+HTTP_COOKIE: <not set>
+HTTP_REFERER: http://127.0.0.1:8000/inspector-protocol/resources/inspector-protocol-page.html
+
+
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/redirect-headers-override2.js b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/redirect-headers-override2.js
new file mode 100644
index 0000000..4b80ec6
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/redirect-headers-override2.js
@@ -0,0 +1,24 @@
+(async function(testRunner) {
+  const {session, dp} = await testRunner.startBlank(
+      `Tests overridden headers don't stick if redirected request is not intercepted following a redirect`);
+
+  await dp.Fetch.enable();
+
+  // Note Referer still sticks due to implementation limitations.
+  const final_url = 'http://127.0.0.1:8000/inspector-protocol//network/resources/echo-headers.php?headers=HTTP_X_DEVTOOLS_TEST:HTTP_COOKIE:HTTP_REFERER';
+  const contentPromise = session.evaluateAsync(`
+    fetch('http://127.0.0.1:8000/inspector-protocol/fetch/resources/redirect.pl?${final_url}').then(r => r.text())
+  `);
+
+  const beforeRedirect = (await dp.Fetch.onceRequestPaused()).params;
+  dp.Fetch.continueRequest({
+    requestId: beforeRedirect.requestId,
+    headers: [
+      {name: 'X-Devtools-Test', value: 'foo'},
+      {name: 'Cookie', value: 'bar=bazz'}
+    ]
+  });
+  dp.Fetch.disable();
+  testRunner.log(await contentPromise);
+  testRunner.completeTest();
+})
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/page/attached-heavy-ad-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/page/attached-heavy-ad-expected.txt
index eb109af..7e8bcc4 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/page/attached-heavy-ad-expected.txt
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/page/attached-heavy-ad-expected.txt
@@ -1,4 +1,5 @@
 Tests that the script which caused the frame to be labelled as an ad is reported on frame attachmend
 
 has adScriptId: true
+has adScriptId via getAdScriptId: true
 
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/page/attached-heavy-ad.js b/third_party/blink/web_tests/http/tests/inspector-protocol/page/attached-heavy-ad.js
index aaacfb15..59e61652 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/page/attached-heavy-ad.js
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/page/attached-heavy-ad.js
@@ -16,5 +16,8 @@
   `);
   const {params} = await secondFrameAttached;
   testRunner.log('has adScriptId: ' + !!params.adScriptId);
+
+  const { result } = await dp.Page.getAdScriptId({ frameId: params.frameId });
+  testRunner.log('has adScriptId via getAdScriptId: ' + !!result.adScriptId);
   testRunner.completeTest();
 })
diff --git a/third_party/blink/web_tests/virtual/pending-beacon/README.md b/third_party/blink/web_tests/virtual/pending-beacon/README.md
index 4850c08..4e38fa7 100644
--- a/third_party/blink/web_tests/virtual/pending-beacon/README.md
+++ b/third_party/blink/web_tests/virtual/pending-beacon/README.md
@@ -1,7 +1,7 @@
 # PendingBeacon Virtual Tests
 
 This folder contains virtual test suites for the PendingBeacon feature.
-The suite runs `web_tests/external/wpt/pending_beacon/` with `--enable-features=PendingBeaconAPI`.
+The suite runs `web_tests/external/wpt/unload-beacon/` with `--enable-features=PendingBeaconAPI`.
 
 To manually run the suites, use the following command:
 
@@ -14,5 +14,5 @@
 To run single test:
 
 ```bash
-third_party/blink/tools/run_web_tests.py -t Default virtual/pending-beacon/external/wpt/pending_beacon/pending_beacon-basic.tentative.window.html
+third_party/blink/tools/run_web_tests.py -t Default virtual/pending-beacon/external/wpt/unload-beacon/pending_beacon-basic.tentative.window.html
 ```
diff --git a/third_party/blink/web_tests/wpt_internal/pending_beacon/README.md b/third_party/blink/web_tests/wpt_internal/unload-beacon/README.md
similarity index 70%
rename from third_party/blink/web_tests/wpt_internal/pending_beacon/README.md
rename to third_party/blink/web_tests/wpt_internal/unload-beacon/README.md
index 8c4d45fe..1666f16 100644
--- a/third_party/blink/web_tests/wpt_internal/pending_beacon/README.md
+++ b/third_party/blink/web_tests/wpt_internal/unload-beacon/README.md
@@ -1,8 +1,9 @@
-# PendingBeacon WPT tests
+# Page Unload Beacon WPT tests
 
 This directory contains [Web Platform
 Tests](third_party/blink/web_tests/external/wpt) for
-[PendingBeacon API](https://wicg.github.io/unload-beacon).
+[Page Unload Beacon API](https://wicg.github.io/unload-beacon), a.k.a.
+PendingBeacon API.
 
 These tests are generally intended to be upstreamed to the Web Platform Tests
 repository (i.e., moved from `wpt_internal`/ to `external/wpt`).
diff --git a/third_party/blink/web_tests/wpt_internal/pending_beacon/pending_beacon-sendondiscard.tentative.window.js b/third_party/blink/web_tests/wpt_internal/unload-beacon/pending_beacon-sendondiscard.tentative.window.js
similarity index 92%
rename from third_party/blink/web_tests/wpt_internal/pending_beacon/pending_beacon-sendondiscard.tentative.window.js
rename to third_party/blink/web_tests/wpt_internal/unload-beacon/pending_beacon-sendondiscard.tentative.window.js
index 4498967..d7f2c6d 100644
--- a/third_party/blink/web_tests/wpt_internal/pending_beacon/pending_beacon-sendondiscard.tentative.window.js
+++ b/third_party/blink/web_tests/wpt_internal/unload-beacon/pending_beacon-sendondiscard.tentative.window.js
@@ -1,7 +1,7 @@
 // META: script=/resources/testharness.js
 // META: script=/resources/testharnessreport.js
 // META: script=/common/utils.js
-// META: script=/pending_beacon/resources/pending_beacon-helper.js
+// META: script=/unload-beacon/resources/pending_beacon-helper.js
 
 'use strict';
 
@@ -22,7 +22,7 @@
 
 parallelPromiseTest(async t => {
   const uuid = token();
-  const url = `/pending_beacon/resources/set_beacon.py?uuid=${uuid}`;
+  const url = generateSetBeaconURL(uuid);
   const numPerMethod = 20;
   const total = numPerMethod * 2;
   // "Sending beacon on page discard" requires BackgroundSync permission.
@@ -46,7 +46,7 @@
 
 parallelPromiseTest(async t => {
   const uuid = token();
-  const url = `/pending_beacon/resources/set_beacon.py?uuid=${uuid}`;
+  const url = generateSetBeaconURL(uuid);
   // "Sending beacon on page discard" requires BackgroundSync permission.
   await setBackgroundSyncEnabled(true);
 
@@ -67,7 +67,7 @@
 
 parallelPromiseTest(async t => {
   const uuid = token();
-  const url = `/pending_beacon/resources/set_beacon.py?uuid=${uuid}`;
+  const url = generateSetBeaconURL(uuid);
   const numPerMethod = 20;
   const total = numPerMethod * 2;
   // "Sending beacon on page discard" requires BackgroundSync permission.
@@ -94,7 +94,7 @@
 
 parallelPromiseTest(async t => {
   const uuid = token();
-  const url = `/pending_beacon/resources/set_beacon.py?uuid=${uuid}`;
+  const url = generateSetBeaconURL(uuid);
   const numPerMethod = 20;
   const total = numPerMethod * 2;
   // "Sending beacon on page discard" requires BackgroundSync permission.
diff --git a/tools/clang/plugins/BlinkDataMemberTypeChecker.cpp b/tools/clang/plugins/BlinkDataMemberTypeChecker.cpp
index f85b782c..52c2118c 100644
--- a/tools/clang/plugins/BlinkDataMemberTypeChecker.cpp
+++ b/tools/clang/plugins/BlinkDataMemberTypeChecker.cpp
@@ -51,7 +51,7 @@
 
 void BlinkDataMemberTypeChecker::CheckClass(SourceLocation location,
                                             const CXXRecordDecl* record) {
-  std::string filename = GetFilename(instance_, location);
+  std::string filename = GetFilename(instance_.getSourceManager(), location);
   if (!included_filenames_regex_.match(filename))
     return;
   if (excluded_filenames_regex_.match(filename))
diff --git a/tools/clang/plugins/CMakeLists.txt b/tools/clang/plugins/CMakeLists.txt
index 0c0c4aa..d07457f8 100644
--- a/tools/clang/plugins/CMakeLists.txt
+++ b/tools/clang/plugins/CMakeLists.txt
@@ -3,6 +3,7 @@
   ChromeClassTester.cpp
   FindBadConstructsAction.cpp
   FindBadConstructsConsumer.cpp
+  FindBadRawPtrPatterns.cpp
   CheckIPCVisitor.cpp
   CheckLayoutObjectMethodsVisitor.cpp
   Util.cpp
diff --git a/tools/clang/plugins/ChromeClassTester.cpp b/tools/clang/plugins/ChromeClassTester.cpp
index a76d59ff..603e2c8b 100644
--- a/tools/clang/plugins/ChromeClassTester.cpp
+++ b/tools/clang/plugins/ChromeClassTester.cpp
@@ -71,7 +71,7 @@
   if (instance().getSourceManager().isInSystemHeader(loc))
     return LocationType::kThirdParty;
 
-  std::string filename = GetFilename(instance(), loc);
+  std::string filename = GetFilename(instance().getSourceManager(), loc);
   if (filename.empty()) {
     // If the filename cannot be determined, simply treat this as a banned
     // location, instead of going through the full lookup process.
@@ -139,7 +139,7 @@
   // If |record_location| is a macro, check the whole chain of expansions.
   const SourceManager& source_manager = instance_.getSourceManager();
   while (true) {
-    filename = GetFilename(instance(), record_location);
+    filename = GetFilename(instance().getSourceManager(), record_location);
     if (ends_with(filename, ".cc") || ends_with(filename, ".cpp") ||
         ends_with(filename, ".mm")) {
       return true;
diff --git a/tools/clang/plugins/FindBadConstructsAction.cpp b/tools/clang/plugins/FindBadConstructsAction.cpp
index 698b4a8..c6ea3bc 100644
--- a/tools/clang/plugins/FindBadConstructsAction.cpp
+++ b/tools/clang/plugins/FindBadConstructsAction.cpp
@@ -55,6 +55,8 @@
       options_.check_layout_object_methods = true;
     } else if (args[i] == "raw-ref-template-as-trivial-member") {
       options_.raw_ref_template_as_trivial_member = true;
+    } else if (args[i] == "check-bad-raw-ptr-cast") {
+      options_.check_bad_raw_ptr_cast = true;
     } else {
       parsed = false;
       llvm::errs() << "Unknown clang plugin argument: " << args[i] << "\n";
diff --git a/tools/clang/plugins/FindBadConstructsConsumer.cpp b/tools/clang/plugins/FindBadConstructsConsumer.cpp
index 6177ca1..4b605ba7 100644
--- a/tools/clang/plugins/FindBadConstructsConsumer.cpp
+++ b/tools/clang/plugins/FindBadConstructsConsumer.cpp
@@ -4,6 +4,7 @@
 
 #include "FindBadConstructsConsumer.h"
 
+#include "FindBadRawPtrPatterns.h"
 #include "Util.h"
 #include "clang/AST/Attr.h"
 #include "clang/Frontend/CompilerInstance.h"
@@ -230,6 +231,7 @@
   RecursiveASTVisitor::TraverseDecl(context.getTranslationUnitDecl());
   if (ipc_visitor_)
     ipc_visitor_->set_context(nullptr);
+  FindBadRawPtrPatterns(options_, context, instance());
 }
 
 bool FindBadConstructsConsumer::TraverseDecl(Decl* decl) {
diff --git a/tools/clang/plugins/FindBadRawPtrPatterns.cpp b/tools/clang/plugins/FindBadRawPtrPatterns.cpp
new file mode 100644
index 0000000..d86854a
--- /dev/null
+++ b/tools/clang/plugins/FindBadRawPtrPatterns.cpp
@@ -0,0 +1,105 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "FindBadRawPtrPatterns.h"
+
+#include "Util.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/ASTMatchers/ASTMatchersMacros.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/Support/LineIterator.h"
+
+using namespace clang;
+using namespace clang::ast_matchers;
+
+namespace chrome_checker {
+
+const char kBadCastSignature[] =
+    "[chromium-raw-ptr-cast] Casting raw_ptr<T>* to another type is not "
+    "allowed as it may cause BRP ref count mismatch and bypass security "
+    "checks.";
+
+class BadCastMatcher : public MatchFinder::MatchCallback {
+ public:
+  explicit BadCastMatcher(clang::CompilerInstance& compiler)
+      : compiler_(compiler) {
+    error_bad_raw_ptr_cast_signature_ =
+        compiler_.getDiagnostics().getCustomDiagID(
+            clang::DiagnosticsEngine::Error, kBadCastSignature);
+  }
+
+  void Register(MatchFinder& match_finder) {
+    // TODO(keishi): Also find casts to and from classes that contain raw_ptr.
+    auto cast_matcher =
+        castExpr(
+            allOf(hasSourceExpression(hasType(pointerType(pointee(
+                      hasUnqualifiedDesugaredType(recordType(hasDeclaration(
+                          cxxRecordDecl(classTemplateSpecializationDecl(
+                              hasName("base::raw_ptr")))))))))),
+                  hasCastKind(CK_BitCast)))
+            .bind("castExpr");
+    match_finder.addMatcher(cast_matcher, this);
+  }
+
+  void run(const MatchFinder::MatchResult& result) override {
+    const clang::CastExpr* cast_expr =
+        result.Nodes.getNodeAs<clang::CastExpr>("castExpr");
+    assert(cast_expr && "matcher should bind 'castExpr'");
+
+    const clang::SourceManager& source_manager = *result.SourceManager;
+    clang::SourceLocation loc = cast_expr->getSourceRange().getBegin();
+    std::string file_path = GetFilename(source_manager, loc);
+
+    // Using raw_ptr<T> in a stdlib collection will cause a cast.
+    // e.g.
+    // https://source.chromium.org/chromium/chromium/src/+/main:components/feed/core/v2/xsurface_datastore.h;drc=a0ff03edcace35ec020edd235f4d9e9735fc9690;l=107
+    if (file_path.find("buildtools/third_party/libc++") != std::string::npos)
+      return;
+    // CHECK(raw_ptr<T>) will cause a cast.
+    // e.g.
+    // https://source.chromium.org/chromium/chromium/src/+/main:base/task/sequence_manager/thread_controller_with_message_pump_impl.cc;drc=c49b7434a9d4a61c49fc0123e904a6c5e7162731;l=121
+    if (file_path.find("base/check_op.h") != std::string::npos)
+      return;
+    // raw_ptr<T>* is cast to ui::metadata::PropertyKey
+    // https://source.chromium.org/chromium/chromium/src/+/main:ui/views/view.cc;drc=a0ff03edcace35ec020edd235f4d9e9735fc9690;l=2417
+    if (file_path.find("ui/views/controls/table/table_view.cc") !=
+        std::string::npos)
+      return;
+    // XdgActivation::activation_queue_ is a base::queue<raw_ptr> which causes a
+    // cast in VectorBuffer and circular_deque.
+    if (file_path.find("base/containers/vector_buffer.h") != std::string::npos)
+      return;
+    if (file_path.find("base/containers/circular_deque.h") != std::string::npos)
+      return;
+
+    compiler_.getDiagnostics().Report(cast_expr->getEndLoc(),
+                                      error_bad_raw_ptr_cast_signature_);
+  }
+
+ private:
+  clang::CompilerInstance& compiler_;
+  unsigned error_bad_raw_ptr_cast_signature_;
+};
+
+void FindBadRawPtrPatterns(Options options,
+                           clang::ASTContext& ast_context,
+                           clang::CompilerInstance& compiler) {
+  if (!options.check_bad_raw_ptr_cast)
+    return;
+  MatchFinder match_finder;
+
+  BadCastMatcher bad_cast_matcher(compiler);
+  bad_cast_matcher.Register(match_finder);
+
+  match_finder.matchAST(ast_context);
+}
+
+}  // namespace chrome_checker
diff --git a/tools/clang/plugins/FindBadRawPtrPatterns.h b/tools/clang/plugins/FindBadRawPtrPatterns.h
new file mode 100644
index 0000000..870b2d3
--- /dev/null
+++ b/tools/clang/plugins/FindBadRawPtrPatterns.h
@@ -0,0 +1,20 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TOOLS_CLANG_PLUGINS_FINDBADRAWPTRPATTERNS_H_
+#define TOOLS_CLANG_PLUGINS_FINDBADRAWPTRPATTERNS_H_
+
+#include "Options.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Frontend/CompilerInstance.h"
+
+namespace chrome_checker {
+
+void FindBadRawPtrPatterns(Options options,
+                           clang::ASTContext& ast_context,
+                           clang::CompilerInstance& compiler);
+
+}  // namespace chrome_checker
+
+#endif  // TOOLS_CLANG_PLUGINS_FINDBADRAWPTRPATTERNS_H_
diff --git a/tools/clang/plugins/Options.h b/tools/clang/plugins/Options.h
index e06a971..e016193 100644
--- a/tools/clang/plugins/Options.h
+++ b/tools/clang/plugins/Options.h
@@ -13,6 +13,7 @@
   bool check_ipc = false;
   bool check_layout_object_methods = false;
   bool raw_ref_template_as_trivial_member = false;
+  bool check_bad_raw_ptr_cast = false;
 };
 
 }  // namespace chrome_checker
diff --git a/tools/clang/plugins/Util.cpp b/tools/clang/plugins/Util.cpp
index 73641113..5b6ebb41 100644
--- a/tools/clang/plugins/Util.cpp
+++ b/tools/clang/plugins/Util.cpp
@@ -37,9 +37,8 @@
   return GetNamespaceImpl(record->getDeclContext(), std::string());
 }
 
-std::string GetFilename(clang::CompilerInstance& instance,
+std::string GetFilename(const clang::SourceManager& source_manager,
                         clang::SourceLocation location) {
-  const clang::SourceManager& source_manager = instance.getSourceManager();
   clang::SourceLocation spelling_location =
       source_manager.getSpellingLoc(location);
   clang::PresumedLoc ploc = source_manager.getPresumedLoc(spelling_location);
diff --git a/tools/clang/plugins/Util.h b/tools/clang/plugins/Util.h
index 02f7edd..01f05b6 100644
--- a/tools/clang/plugins/Util.h
+++ b/tools/clang/plugins/Util.h
@@ -9,7 +9,7 @@
 
 #include "clang/AST/DeclBase.h"
 #include "clang/Basic/SourceLocation.h"
-#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Basic/SourceManager.h"
 
 // Utility method for subclasses to determine the namespace of the
 // specified record, if any. Unnamed namespaces will be identified as
@@ -18,7 +18,7 @@
 
 // Attempts to determine the filename for the given SourceLocation.
 // Returns an empty string if the filename could not be determined.
-std::string GetFilename(clang::CompilerInstance& instance,
+std::string GetFilename(const clang::SourceManager& instance,
                         clang::SourceLocation location);
 
 #endif  // TOOLS_CLANG_PLUGINS_UTIL_H_
diff --git a/tools/clang/plugins/tests/bad_raw_ptr_cast.cpp b/tools/clang/plugins/tests/bad_raw_ptr_cast.cpp
new file mode 100644
index 0000000..5eaaf80
--- /dev/null
+++ b/tools/clang/plugins/tests/bad_raw_ptr_cast.cpp
@@ -0,0 +1,17 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "bad_raw_ptr_cast.h"
+
+#include <cstring>
+
+void BadRawPtr::Check() {
+  // Explicit cast from raw_ptr<T>* is not allowed.
+  void* bar = reinterpret_cast<void*>(&foo_);
+  bar = static_cast<void*>(&foo_);
+  bar = (void*)&foo_;
+  // Implicit cast from raw_ptr<T>* is not allowed.
+  bar = &foo_;
+  memcpy(&foo_, &foo_, 1);
+}
diff --git a/tools/clang/plugins/tests/bad_raw_ptr_cast.flags b/tools/clang/plugins/tests/bad_raw_ptr_cast.flags
new file mode 100644
index 0000000..f56a9561
--- /dev/null
+++ b/tools/clang/plugins/tests/bad_raw_ptr_cast.flags
@@ -0,0 +1 @@
+-Xclang -plugin-arg-find-bad-constructs -Xclang check-bad-raw-ptr-cast
diff --git a/tools/clang/plugins/tests/bad_raw_ptr_cast.h b/tools/clang/plugins/tests/bad_raw_ptr_cast.h
new file mode 100644
index 0000000..98b291e
--- /dev/null
+++ b/tools/clang/plugins/tests/bad_raw_ptr_cast.h
@@ -0,0 +1,18 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TOOLS_CLANG_PLUGINS_TESTS_BAD_RAW_PTR_CAST_H_
+#define TOOLS_CLANG_PLUGINS_TESTS_BAD_RAW_PTR_CAST_H_
+
+#include "base/memory/raw_ptr.h"
+
+class BadRawPtr {
+ public:
+  void Check();
+
+ private:
+  raw_ptr<int> foo_;
+};
+
+#endif  // TOOLS_CLANG_PLUGINS_TESTS_BAD_RAW_PTR_CAST_H_
\ No newline at end of file
diff --git a/tools/clang/plugins/tests/bad_raw_ptr_cast.txt b/tools/clang/plugins/tests/bad_raw_ptr_cast.txt
new file mode 100644
index 0000000..a1a11ba
--- /dev/null
+++ b/tools/clang/plugins/tests/bad_raw_ptr_cast.txt
@@ -0,0 +1,19 @@
+bad_raw_ptr_cast.cpp:11:44: error: [chromium-raw-ptr-cast] Casting raw_ptr<T>* to another type is not allowed as it may cause BRP ref count mismatch and bypass security checks.
+  void* bar = reinterpret_cast<void*>(&foo_);
+                                           ^
+bad_raw_ptr_cast.cpp:12:29: error: [chromium-raw-ptr-cast] Casting raw_ptr<T>* to another type is not allowed as it may cause BRP ref count mismatch and bypass security checks.
+  bar = static_cast<void*>(&foo_);
+                            ^
+bad_raw_ptr_cast.cpp:13:17: error: [chromium-raw-ptr-cast] Casting raw_ptr<T>* to another type is not allowed as it may cause BRP ref count mismatch and bypass security checks.
+  bar = (void*)&foo_;
+                ^
+bad_raw_ptr_cast.cpp:15:10: error: [chromium-raw-ptr-cast] Casting raw_ptr<T>* to another type is not allowed as it may cause BRP ref count mismatch and bypass security checks.
+  bar = &foo_;
+         ^
+bad_raw_ptr_cast.cpp:16:11: error: [chromium-raw-ptr-cast] Casting raw_ptr<T>* to another type is not allowed as it may cause BRP ref count mismatch and bypass security checks.
+  memcpy(&foo_, &foo_, 1);
+          ^
+bad_raw_ptr_cast.cpp:16:18: error: [chromium-raw-ptr-cast] Casting raw_ptr<T>* to another type is not allowed as it may cause BRP ref count mismatch and bypass security checks.
+  memcpy(&foo_, &foo_, 1);
+                 ^
+6 errors generated.
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py
index 24d1aff8..a6adc313 100755
--- a/tools/clang/scripts/update.py
+++ b/tools/clang/scripts/update.py
@@ -35,8 +35,8 @@
 # https://chromium.googlesource.com/chromium/src/+/main/docs/updating_clang.md
 # Reverting problematic clang rolls is safe, though.
 # This is the output of `git describe` and is usable as a commit-ish.
-CLANG_REVISION = 'llvmorg-16-init-6578-g0d30e92f'
-CLANG_SUB_REVISION = 2
+CLANG_REVISION = 'llvmorg-16-init-7184-gdeb82d4a'
+CLANG_SUB_REVISION = 1
 
 PACKAGE_VERSION = '%s-%s' % (CLANG_REVISION, CLANG_SUB_REVISION)
 RELEASE_VERSION = '16.0.0'
diff --git a/tools/determinism/deterministic_build_ignorelist.pyl b/tools/determinism/deterministic_build_ignorelist.pyl
index 8aef496..6f10c3e7 100644
--- a/tools/determinism/deterministic_build_ignorelist.pyl
+++ b/tools/determinism/deterministic_build_ignorelist.pyl
@@ -108,6 +108,10 @@
 
     # https://crbug.com/1093166
     'test_data/ppapi/tests/extensions/packaged_app/pnacl/ppapi_tests_extensions_packaged_app_newlib_pnacl.pexe',
+
+    # TODO(hans): Remove once clang is fixed.
+    # https://crbug.com/1373836
+    'swiftshader_reactor_llvm_unittests',
   ],
 
   # TODO(thakis): Move mac det bots to use two distinct build dirs,
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index 2e744131..a5e2634 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -6541,7 +6541,6 @@
 
 <action name="ContentSuggestions.Feed.CardAction.Open.StartSurface">
   <owner>hanxi@chromium.org</owner>
-  <owner>spdonghao@chromium.org</owner>
   <owner>clank-start@google.com</owner>
   <description>
     The user tapped on a card in the Feed on the start surface.
@@ -18582,7 +18581,6 @@
 
 <action name="MobileMenuNewTab.StartSurfaceFinale">
   <owner>hanxi@chromium.org</owner>
-  <owner>spdonghao@chromium.org</owner>
   <owner>clank-start@google.com</owner>
   <description>
     User pressed 'New tab' in the app menu when start surface finale is enabled.
@@ -19268,7 +19266,6 @@
 
 <action name="MobileOmniboxUse.StartSurface">
   <owner>hanxi@chromium.org</owner>
-  <owner>spdonghao@chromium.org</owner>
   <owner>clank-start@google.com</owner>
   <description>
     User used the omnibox while it is showing on the start surface.
@@ -26953,7 +26950,6 @@
 
 <action name="SearchResumptionModule.NTP.Click">
   <owner>hanxi@chromium.org</owner>
-  <owner>spdonghao@chromium.org</owner>
   <owner>xinyiji@chromium.org</owner>
   <description>
     The search suggestion on the search resumption module is clicked.
@@ -26962,7 +26958,6 @@
 
 <action name="SearchResumptionModule.NTP.Collapse">
   <owner>hanxi@chromium.org</owner>
-  <owner>spdonghao@chromium.org</owner>
   <owner>xinyiji@chromium.org</owner>
   <description>
     Users click the header of the search resumption module to collapse the
@@ -26972,7 +26967,6 @@
 
 <action name="SearchResumptionModule.NTP.Expand">
   <owner>hanxi@chromium.org</owner>
-  <owner>spdonghao@chromium.org</owner>
   <owner>xinyiji@chromium.org</owner>
   <description>
     Users click the header of the search resumption module to expand and show
@@ -31093,7 +31087,6 @@
 
 <action name="StartSurface.ShownFromBackNavigation">
   <owner>hanxi@chromium.org</owner>
-  <owner>spdonghao@chromium.org</owner>
   <owner>andrewheard@chromium.org</owner>
   <description>
     The Start surface is showing due to the user taps the back button.
@@ -32164,7 +32157,6 @@
 
 <action name="Suggestions.Tile.Tapped.StartSurface">
   <owner>hanxi@chromium.org</owner>
-  <owner>spdonghao@chromium.org</owner>
   <owner>clank-start@google.com</owner>
   <description>
     User tapped on a suggestions tile while viewing the start surface.
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 4d119a45..686ea9b 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -57838,7 +57838,6 @@
   <int value="-1460462432" label="disable-media-source"/>
   <int value="-1459907288" label="DesksTemplates:enabled"/>
   <int value="-1459246132" label="kWebSQLAccess:disabled"/>
-  <int value="-1458056084" label="SyncUndecryptablePasswordsLinux:enabled"/>
   <int value="-1457775295" label="PasswordSearchMobile:disabled"/>
   <int value="-1456789591" label="MediaFoundationVideoCapture:enabled"/>
   <int value="-1456627355" label="EnableEmojiContextMenu:disabled"/>
@@ -58821,7 +58820,6 @@
   <int value="-894214299" label="fill-on-account-select:enabled"/>
   <int value="-894185031" label="HighDynamicRange:disabled"/>
   <int value="-893673593" label="BentoOffline:disabled"/>
-  <int value="-893656784" label="SyncUndecryptablePasswordsLinux:disabled"/>
   <int value="-892428689" label="ManualPasswordGenerationAndroid:enabled"/>
   <int value="-892297699" label="EditContext:enabled"/>
   <int value="-891856063" label="MidiManagerAndroid:enabled"/>
@@ -100457,6 +100455,14 @@
   <int value="5" label="Rejected: Is a Google domain, but not https."/>
 </enum>
 
+<enum name="VariationsInvalidLayerReason">
+  <int value="0" label="Invalid ID"/>
+  <int value="1" label="No slots"/>
+  <int value="2" label="No members"/>
+  <int value="3" label="Invalid entropy mode"/>
+  <int value="4" label="Slots do not divide low entropy domain"/>
+</enum>
+
 <enum name="VariationsInvalidStudyReason">
   <int value="0" label="Invalid min_version"/>
   <int value="1" label="Invalid max_version"/>
diff --git a/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS b/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS
index c9dd8fe..6feccd2 100644
--- a/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS
+++ b/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS
@@ -346,8 +346,6 @@
 drubery@chromium.org
 thefrog@chromium.org
 xinghuilu@chromium.org
-# startup
-spdonghao@chromium.org
 # storage
 ayui@chromium.org
 wanderview@chromium.org
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml
index 2e4345c..22e9466a 100644
--- a/tools/metrics/histograms/metadata/ash/histograms.xml
+++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -4924,6 +4924,16 @@
   </token>
 </histogram>
 
+<histogram name="Ash.UserImage.URLLoaderDownloadSuccess" enum="BooleanSuccess"
+    expires_after="M115">
+  <owner>angelaxiao@google.com</owner>
+  <owner>updowndota@google.com</owner>
+  <summary>
+    Emitted when loading default user images from gstatic resources. Records
+    whether an image download attempt was successful or not.
+  </summary>
+</histogram>
+
 <histogram name="Ash.Wallpaper.Collection" enum="WallpaperCollection"
     expires_after="2023-05-17">
   <owner>jasontt@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/input/histograms.xml b/tools/metrics/histograms/metadata/input/histograms.xml
index 0094246..8b3d9ad 100644
--- a/tools/metrics/histograms/metadata/input/histograms.xml
+++ b/tools/metrics/histograms/metadata/input/histograms.xml
@@ -407,11 +407,13 @@
   <owner>curtismcmullan@google.com</owner>
   <owner>essential-inputs-team@google.com</owner>
   <summary>
-    This histogram records when the current text context could possibly show a
-    suggestion. This does not necessarily mean a suggestion was shown, only that
-    the current text context fulfills all constraints needed to trigger an
-    attempt to generate and display suggestions. It is recorded exactly once per
-    surrounding text update.
+    DEPRECATED, please see
+    InputMethod.Assistive.MultiWord.SuggestionOpportunity. This histogram
+    records when the current text context could possibly show a suggestion. This
+    does not necessarily mean a suggestion was shown, only that the current text
+    context fulfills all constraints needed to trigger an attempt to generate
+    and display suggestions. It is recorded exactly once per surrounding text
+    update.
   </summary>
 </histogram>
 
@@ -460,6 +462,19 @@
   </summary>
 </histogram>
 
+<histogram name="InputMethod.Assistive.MultiWord.SuggestionOpportunity"
+    enum="IMEAssistiveMultiWordSuggestionType" expires_after="2023-03-05">
+  <owner>curtismcmullan@google.com</owner>
+  <owner>essential-inputs-team@google.com</owner>
+  <summary>
+    This histogram records when the current text context could possibly show a
+    suggestion. This does not necessarily mean a suggestion was shown, only that
+    the current text context fulfills all constraints needed to trigger an
+    attempt to generate and display suggestions. It is recorded exactly once per
+    surrounding text update.
+  </summary>
+</histogram>
+
 <histogram name="InputMethod.Assistive.NotAllowed" enum="IMEAssistiveAction"
     expires_after="2023-05-01">
   <owner>jiwan@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/ios/histograms.xml b/tools/metrics/histograms/metadata/ios/histograms.xml
index d12cb6c..caac814 100644
--- a/tools/metrics/histograms/metadata/ios/histograms.xml
+++ b/tools/metrics/histograms/metadata/ios/histograms.xml
@@ -1764,7 +1764,7 @@
 </histogram>
 
 <histogram name="IOS.TabGrid.Selection.AddToBookmarks" units="Tabs"
-    expires_after="2022-11-01">
+    expires_after="2023-11-01">
   <owner>mrefaat@chromium.org</owner>
   <owner>michaeldo@chromium.org</owner>
   <owner>bling-team@google.com</owner>
@@ -1775,7 +1775,7 @@
 </histogram>
 
 <histogram name="IOS.TabGrid.Selection.AddToReadingList" units="Tabs"
-    expires_after="2022-11-01">
+    expires_after="2023-11-01">
   <owner>mrefaat@chromium.org</owner>
   <owner>michaeldo@chromium.org</owner>
   <owner>bling-team@google.com</owner>
@@ -1786,7 +1786,7 @@
 </histogram>
 
 <histogram name="IOS.TabGrid.Selection.CloseTabs" units="Tabs"
-    expires_after="2022-10-16">
+    expires_after="2023-11-01">
   <owner>mrefaat@chromium.org</owner>
   <owner>michaeldo@chromium.org</owner>
   <owner>bling-team@google.com</owner>
@@ -1797,7 +1797,7 @@
 </histogram>
 
 <histogram name="IOS.TabGrid.Selection.ShareTabs" units="Tabs"
-    expires_after="2022-11-01">
+    expires_after="2023-11-01">
   <owner>mrefaat@chromium.org</owner>
   <owner>michaeldo@chromium.org</owner>
   <owner>bling-team@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml
index 368638a5..6904fda 100644
--- a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml
+++ b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml
@@ -884,7 +884,6 @@
     enum="FeedPositionSegmentationResult" expires_after="2022-11-15">
   <owner>hanxi@chromium.org</owner>
   <owner>ssid@chromium.org</owner>
-  <owner>spdonghao@chromium.org</owner>
   <summary>
     Logs the result from segmentation platform that determines whether the user
     is a Feed active user or a non-Feed user. Recorded three times when a new
@@ -1693,7 +1692,6 @@
     enum="SearchResumptionModule.ModuleNotShownReason"
     expires_after="2023-04-30">
   <owner>hanxi@chromium.org</owner>
-  <owner>spdonghao@chromium.org</owner>
   <summary>
     Logs the reason why the search resumption module is enabled but not shown on
     the NTP. Recorded when NewTabPage is created and the search resumption
@@ -1704,7 +1702,6 @@
 <histogram name="NewTabPage.SearchResumptionModule.Show"
     enum="SearchResumptionModule.ModuleShowStatus" expires_after="2023-03-05">
   <owner>hanxi@chromium.org</owner>
-  <owner>spdonghao@chromium.org</owner>
   <summary>
     Logs whether the search resumption module is expanded or collapsed when the
     module is shown on the NTP. Recorded when the NewTabPage is created and the
@@ -1715,7 +1712,6 @@
 <histogram name="NewTabPage.SearchResumptionModule.Show.Cached"
     enum="SearchResumptionModule.ModuleShowStatus" expires_after="2023-03-05">
   <owner>hanxi@chromium.org</owner>
-  <owner>spdonghao@chromium.org</owner>
   <owner>xinyiji@chromium.org</owner>
   <summary>
     Logs whether the search resumption module is expanded or collapsed when the
diff --git a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
index e7cf2b3..4f695e5 100644
--- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
+++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -2662,6 +2662,23 @@
   </summary>
 </histogram>
 
+<histogram name="SafeBrowsing.{Process}Throttle.IntervalBetweenStartAndProcess"
+    units="ms" expires_after="2023-10-13">
+  <owner>xinghuilu@chromium.org</owner>
+  <owner>chrome-counter-abuse-alerts@google.com</owner>
+  <summary>
+    Logs the interval between when the {Process} URL loader starts a request and
+    when the {Process} URL loader is ready to process the response. Logs each
+    time the URL loader is ready to process the response and the start request
+    function is previously called. During this interval, Safe Browsing checks
+    are performend in parallel.
+  </summary>
+  <token key="Process">
+    <variant name="Browser" summary="browser"/>
+    <variant name="Renderer" summary="renderer"/>
+  </token>
+</histogram>
+
 <histogram name="SafeBrowsingBinaryUploadRequest.DlpResult"
     enum="BooleanSuccess" expires_after="2023-05-01">
   <owner>domfc@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/startup/OWNERS b/tools/metrics/histograms/metadata/startup/OWNERS
index d3aabf6f..4c3c661 100644
--- a/tools/metrics/histograms/metadata/startup/OWNERS
+++ b/tools/metrics/histograms/metadata/startup/OWNERS
@@ -1,5 +1 @@
-per-file OWNERS=file://tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS
-
-# Prefer sending CLs to the owners listed below.
-# Use chromium-metrics-reviews@google.com as a backup.
-spdonghao@chromium.org
\ No newline at end of file
+per-file OWNERS=file://tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS
\ No newline at end of file
diff --git a/tools/metrics/histograms/metadata/startup/histograms.xml b/tools/metrics/histograms/metadata/startup/histograms.xml
index 147396a..97a76fd 100644
--- a/tools/metrics/histograms/metadata/startup/histograms.xml
+++ b/tools/metrics/histograms/metadata/startup/histograms.xml
@@ -43,7 +43,6 @@
 <histogram name="Startup.Android.CachedFeedVisibilityConsistency"
     enum="BooleanConsistent" expires_after="2023-03-05">
   <owner>hanxi@chromium.org</owner>
-  <owner>spdonghao@chromium.org</owner>
   <owner>wychen@chromium.org</owner>
   <summary>
     Records whether or not the cached Feed visibility in the SharedPreferences
@@ -208,7 +207,6 @@
 <histogram name="Startup.Android.DurationSinceLastBackgroundTime" units="ms"
     expires_after="2023-03-05">
   <owner>hanxi@chromium.org</owner>
-  <owner>spdonghao@chromium.org</owner>
   <summary>
     Android: The elapsed time from the last time when Chrome goes to background
     till it becomes foreground again. The histogram is recorded when
@@ -221,7 +219,6 @@
 <!-- Name completed by histogram_suffixes name="JavaStartMode" -->
 
   <owner>hanxi@chromium.org</owner>
-  <owner>spdonghao@chromium.org</owner>
   <owner>wychen@chromium.org</owner>
   <summary>
     Records the time duration from a cold start till the Feeds articles are
@@ -234,7 +231,6 @@
 <histogram name="Startup.Android.FeedsLoadingPlaceholderShown.Instant"
     units="ms" expires_after="2023-01-15">
   <owner>hanxi@chromium.org</owner>
-  <owner>spdonghao@chromium.org</owner>
   <owner>wychen@chromium.org</owner>
   <summary>
     Records the time duration from a cold start till the Feeds loading
@@ -249,7 +245,6 @@
 <!-- Name completed by histogram_suffixes name="JavaStartMode" -->
 
   <owner>hanxi@chromium.org</owner>
-  <owner>spdonghao@chromium.org</owner>
   <owner>wychen@chromium.org</owner>
   <summary>
     Records the time duration from a cold start till the Feeds stream is created
@@ -263,7 +258,6 @@
 <!-- Name completed by histogram_suffixes name="JavaStartMode" -->
 
   <owner>hanxi@chromium.org</owner>
-  <owner>spdonghao@chromium.org</owner>
   <owner>wychen@chromium.org</owner>
   <summary>
     Records the time duration from a cold start till the first draw completes.
@@ -283,7 +277,6 @@
 <histogram name="Startup.Android.LastVisitedTabIsSRPWhenOverviewShownAtLaunch"
     enum="Boolean" expires_after="2023-02-12">
   <owner>hanxi@chromium.org</owner>
-  <owner>spdonghao@chromium.org</owner>
   <owner>fredmello@chromium.org</owner>
   <summary>
     Records whether or not the last visited tab is a search result page when
@@ -333,7 +326,6 @@
 <!-- Name completed by histogram_suffixes name="JavaStartMode" -->
 
   <owner>hanxi@chromium.org</owner>
-  <owner>spdonghao@chromium.org</owner>
   <owner>wychen@chromium.org</owner>
   <summary>
     Records the time duration from a cold start till the title of the single Tab
@@ -346,7 +338,6 @@
 <histogram name="Startup.Android.StartSurfaceShownAtStartup" enum="Boolean"
     expires_after="2023-02-12">
   <owner>hanxi@chromium.org</owner>
-  <owner>spdonghao@chromium.org</owner>
   <owner>wychen@chromium.org</owner>
   <summary>
     Records whether the Start surface homepage is showing at a cold startup when
diff --git a/tools/metrics/histograms/metadata/v8/histograms.xml b/tools/metrics/histograms/metadata/v8/histograms.xml
index 2c90d1dc..9c5ac8f 100644
--- a/tools/metrics/histograms/metadata/v8/histograms.xml
+++ b/tools/metrics/histograms/metadata/v8/histograms.xml
@@ -348,6 +348,19 @@
   </summary>
 </histogram>
 
+<histogram name="V8.DebugPauseToPausedEventMilliSeconds" units="ms"
+    expires_after="2023-08-01">
+  <owner>bmeurer@chromium.org</owner>
+  <owner>szuend@chromium.org</owner>
+  <owner>chrome-devtools@google.com</owner>
+  <summary>
+    Duration beginning when V8 stops execution due to a breakpoint/exception
+    until the &quot;Debugger.paused&quot; CDP event is sent by the V8 inspector.
+    The event is recorded when all the event data was collected and processed,
+    but before the event is serialized and put on the wire.
+  </summary>
+</histogram>
+
 <histogram name="V8.ErrorsThrownPerContext" units="errors"
     expires_after="2020-02-23">
   <owner>hablich@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/variations/histograms.xml b/tools/metrics/histograms/metadata/variations/histograms.xml
index b92768a..6c7efee 100644
--- a/tools/metrics/histograms/metadata/variations/histograms.xml
+++ b/tools/metrics/histograms/metadata/variations/histograms.xml
@@ -236,6 +236,16 @@
   </token>
 </histogram>
 
+<histogram name="Variations.InvalidLayerReason"
+    enum="VariationsInvalidLayerReason" expires_after="2022-11-20">
+  <owner>holte@chromium.org</owner>
+  <owner>src/base/metrics/OWNERS</owner>
+  <summary>
+    Records the reason for rejecting an invalid layer. Recorded when processing
+    the variations seed at startup and when simulating a new seed.
+  </summary>
+</histogram>
+
 <histogram name="Variations.InvalidStudyReason"
     enum="VariationsInvalidStudyReason" expires_after="2022-11-20">
   <owner>jwd@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/web_rtc/histograms.xml b/tools/metrics/histograms/metadata/web_rtc/histograms.xml
index 27fd461..6b2b632 100644
--- a/tools/metrics/histograms/metadata/web_rtc/histograms.xml
+++ b/tools/metrics/histograms/metadata/web_rtc/histograms.xml
@@ -1364,6 +1364,10 @@
 
 <histogram name="WebRTC.PeerConnection.CandidatePoolUsage.{BundlePolicy}"
     units="components" expires_after="2022-07-01">
+  <obsolete>
+    This measurement showed that numbers higher than 1 are in frequent use for
+    all policies. Experiment is no longer needed.
+  </obsolete>
   <owner>hta@chromium.org</owner>
   <owner>webrtc-dev@chromium.org</owner>
   <summary>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 9a2ab3cf..567fbd5 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -21,8 +21,8 @@
             "full_remote_path": "perfetto-luci-artifacts/v25.0/mac-arm64/trace_processor_shell"
         },
         "linux": {
-            "hash": "b35f0131b281b677c3b3807b61239059e8e34400",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/280f0b23c5c8b98248cf0ccf3d011c4fd4bb74f5/trace_processor_shell"
+            "hash": "543561ebf6745f85c4dd04e79650dea531445497",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/f6d72ec51a69015db402072ea6b24dea2a54ed51/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/ui/accessibility/platform/BUILD.gn b/ui/accessibility/platform/BUILD.gn
index 6437916..1cd9408 100644
--- a/ui/accessibility/platform/BUILD.gn
+++ b/ui/accessibility/platform/BUILD.gn
@@ -181,6 +181,8 @@
         "inspect/ax_inspect_utils_win.h",
         "inspect/ax_tree_formatter_uia_win.cc",
         "inspect/ax_tree_formatter_uia_win.h",
+        "inspect/ax_tree_formatter_win.cc",
+        "inspect/ax_tree_formatter_win.h",
         "uia_registrar_win.cc",
         "uia_registrar_win.h",
       ]
diff --git a/content/browser/accessibility/accessibility_tree_formatter_win.cc b/ui/accessibility/platform/inspect/ax_tree_formatter_win.cc
similarity index 87%
rename from content/browser/accessibility/accessibility_tree_formatter_win.cc
rename to ui/accessibility/platform/inspect/ax_tree_formatter_win.cc
index f3429964..5437c048 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_win.cc
+++ b/ui/accessibility/platform/inspect/ax_tree_formatter_win.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 "content/browser/accessibility/accessibility_tree_formatter_win.h"
+#include "ui/accessibility/platform/inspect/ax_tree_formatter_win.h"
 
 #include <math.h>
 #include <stddef.h>
@@ -20,24 +20,17 @@
 #include "base/values.h"
 #include "base/win/scoped_bstr.h"
 #include "base/win/scoped_variant.h"
-#include "content/browser/accessibility/accessibility_tree_formatter_blink.h"
-#include "content/browser/accessibility/browser_accessibility_manager.h"
-#include "content/public/browser/ax_inspect_factory.h"
 #include "third_party/iaccessible2/ia2_api_all.h"
 #include "ui/accessibility/platform/ax_platform_node_base.h"
+#include "ui/accessibility/platform/ax_platform_tree_manager.h"
 #include "ui/accessibility/platform/inspect/ax_inspect_utils.h"
 #include "ui/accessibility/platform/inspect/ax_inspect_utils_win.h"
 #include "ui/base/win/atl_module.h"
 #include "ui/gfx/win/hwnd_util.h"
 
-namespace content {
+namespace ui {
 
-using ui::AXFormatValue;
-using ui::IAccessible2RoleToString;
-using ui::IAccessible2StateToStringVector;
-using ui::IAccessibleStateToStringVector;
-
-void AccessibilityTreeFormatterWin::AddDefaultFilters(
+void AXTreeFormatterWin::AddDefaultFilters(
     std::vector<AXPropertyFilter>* property_filters) {
   // Too noisy: HOTTRACKED, LINKED, SELECTABLE, IA2_STATE_EDITABLE,
   //            IA2_STATE_OPAQUE, IA2_STATE_SELECTAbLE_TEXT,
@@ -84,35 +77,34 @@
   AddPropertyFilter(property_filters, "OFFSCREEN", AXPropertyFilter::DENY);
 }
 
-AccessibilityTreeFormatterWin::AccessibilityTreeFormatterWin() {
-  ui::win::CreateATLModuleIfNeeded();
+AXTreeFormatterWin::AXTreeFormatterWin() {
+  win::CreateATLModuleIfNeeded();
 }
 
-AccessibilityTreeFormatterWin::~AccessibilityTreeFormatterWin() {}
+AXTreeFormatterWin::~AXTreeFormatterWin() {}
 
-Microsoft::WRL::ComPtr<IAccessible>
-GetIAObject(ui::AXPlatformNodeDelegate* node, LONG& root_x, LONG& root_y) {
+Microsoft::WRL::ComPtr<IAccessible> GetIAObject(AXPlatformNodeDelegate* node,
+                                                LONG& root_x,
+                                                LONG& root_y) {
   DCHECK(node);
-  BrowserAccessibility* node_internal =
-      BrowserAccessibility::FromAXPlatformNodeDelegate(node);
-  DCHECK(node_internal);
-  BrowserAccessibilityManager* root_manager =
-      node_internal->manager()->GetManagerForRootFrame();
+  AXTreeManager* root_manager = node->GetTreeManager()->GetRootManager();
   DCHECK(root_manager);
 
   base::win::ScopedVariant variant_self(CHILDID_SELF);
   LONG root_width, root_height;
 
-  HRESULT hr =
-      root_manager->RootDelegate()->GetNativeViewAccessible()->accLocation(
-          &root_x, &root_y, &root_width, &root_height, variant_self);
+  HRESULT hr = static_cast<AXPlatformTreeManager*>(root_manager)
+                   ->RootDelegate()
+                   ->GetNativeViewAccessible()
+                   ->accLocation(&root_x, &root_y, &root_width, &root_height,
+                                 variant_self);
   DCHECK(SUCCEEDED(hr));
 
   return node->GetNativeViewAccessible();
 }
 
-base::Value::Dict AccessibilityTreeFormatterWin::BuildNode(
-    ui::AXPlatformNodeDelegate* node) const {
+base::Value::Dict AXTreeFormatterWin::BuildNode(
+    AXPlatformNodeDelegate* node) const {
   LONG root_x = 0, root_y = 0;
   Microsoft::WRL::ComPtr<IAccessible> node_ia =
       GetIAObject(node, root_x, root_y);
@@ -122,8 +114,8 @@
   return dict;
 }
 
-base::Value::Dict AccessibilityTreeFormatterWin::BuildTree(
-    ui::AXPlatformNodeDelegate* start) const {
+base::Value::Dict AXTreeFormatterWin::BuildTree(
+    AXPlatformNodeDelegate* start) const {
   LONG root_x = 0, root_y = 0;
   Microsoft::WRL::ComPtr<IAccessible> start_ia =
       GetIAObject(start, root_x, root_y);
@@ -133,7 +125,7 @@
   return dict;
 }
 
-base::Value::Dict AccessibilityTreeFormatterWin::BuildTreeForSelector(
+base::Value::Dict AXTreeFormatterWin::BuildTreeForSelector(
     const AXTreeSelector& selector) const {
   base::Value::Dict dict;
 
@@ -158,17 +150,17 @@
   return dict;
 }
 
-void AccessibilityTreeFormatterWin::RecursiveBuildTree(
+void AXTreeFormatterWin::RecursiveBuildTree(
     const Microsoft::WRL::ComPtr<IAccessible> node,
     base::Value::Dict* dict,
     LONG root_x,
     LONG root_y) const {
-  ui::AXPlatformNode* platform_node =
-      ui::AXPlatformNode::FromNativeViewAccessible(node.Get());
+  AXPlatformNode* platform_node =
+      AXPlatformNode::FromNativeViewAccessible(node.Get());
 
   bool skipChildren = false;
   if (platform_node) {
-    ui::AXPlatformNodeDelegate* delegate = platform_node->GetDelegate();
+    AXPlatformNodeDelegate* delegate = platform_node->GetDelegate();
     DCHECK(delegate);
 
     if (!ShouldDumpNode(*delegate))
@@ -183,7 +175,7 @@
     return;
 
   base::Value::List child_list;
-  for (const ui::MSAAChild& msaa_child : ui::MSAAChildren(node)) {
+  for (const MSAAChild& msaa_child : MSAAChildren(node)) {
     base::Value::Dict child_dict;
 
     Microsoft::WRL::ComPtr<IAccessible> child = msaa_child.AsIAccessible();
@@ -257,7 +249,7 @@
     "ia2_table_cell_row_index",
 };
 
-void AccessibilityTreeFormatterWin::AddProperties(
+void AXTreeFormatterWin::AddProperties(
     const Microsoft::WRL::ComPtr<IAccessible> node,
     base::Value::Dict* dict,
     LONG root_x,
@@ -282,7 +274,7 @@
   return std::u16string();
 }
 
-void AccessibilityTreeFormatterWin::AddMSAAProperties(
+void AXTreeFormatterWin::AddMSAAProperties(
     const Microsoft::WRL::ComPtr<IAccessible> node,
     base::Value::Dict* dict,
     LONG root_x,
@@ -382,13 +374,12 @@
   }
 }
 
-void AccessibilityTreeFormatterWin::AddSimpleDOMNodeProperties(
+void AXTreeFormatterWin::AddSimpleDOMNodeProperties(
     const Microsoft::WRL::ComPtr<IAccessible> node,
     base::Value::Dict* dict) const {
   Microsoft::WRL::ComPtr<ISimpleDOMNode> simple_dom_node;
 
-  if (S_OK !=
-      ui::IA2QueryInterface<ISimpleDOMNode>(node.Get(), &simple_dom_node))
+  if (S_OK != IA2QueryInterface<ISimpleDOMNode>(node.Get(), &simple_dom_node))
     return;
 
   base::win::ScopedBstr bstr;
@@ -398,11 +389,11 @@
   bstr.Reset();
 }
 
-bool AccessibilityTreeFormatterWin::AddIA2Properties(
+bool AXTreeFormatterWin::AddIA2Properties(
     const Microsoft::WRL::ComPtr<IAccessible> node,
     base::Value::Dict* dict) const {
   Microsoft::WRL::ComPtr<IAccessible2> ia2;
-  if (S_OK != ui::IA2QueryInterface<IAccessible2>(node.Get(), &ia2))
+  if (S_OK != IA2QueryInterface<IAccessible2>(node.Get(), &ia2))
     return false;
 
   LONG ia2_role = 0;
@@ -471,11 +462,11 @@
   return true;
 }
 
-void AccessibilityTreeFormatterWin::AddIA2ActionProperties(
+void AXTreeFormatterWin::AddIA2ActionProperties(
     const Microsoft::WRL::ComPtr<IAccessible> node,
     base::Value::Dict* dict) const {
   Microsoft::WRL::ComPtr<IAccessibleAction> ia2action;
-  if (S_OK != ui::IA2QueryInterface<IAccessibleAction>(node.Get(), &ia2action))
+  if (S_OK != IA2QueryInterface<IAccessibleAction>(node.Get(), &ia2action))
     return;
 
   // |IAccessibleAction::get_name| returns a localized string.
@@ -486,12 +477,11 @@
   }
 }
 
-void AccessibilityTreeFormatterWin::AddIA2HypertextProperties(
+void AXTreeFormatterWin::AddIA2HypertextProperties(
     Microsoft::WRL::ComPtr<IAccessible> node,
     base::Value::Dict* dict) const {
   Microsoft::WRL::ComPtr<IAccessibleHypertext> ia2hyper;
-  if (S_OK !=
-      ui::IA2QueryInterface<IAccessibleHypertext>(node.Get(), &ia2hyper))
+  if (S_OK != IA2QueryInterface<IAccessibleHypertext>(node.Get(), &ia2hyper))
     return;
 
   base::win::ScopedBstr text_bstr;
@@ -509,12 +499,12 @@
     // Replace all embedded characters with the child indices of the
     // accessibility objects they refer to.
     std::wstring embedded_character = base::UTF16ToWide(
-        std::u16string(1, ui::AXPlatformNodeBase::kEmbeddedCharacter));
+        std::u16string(1, AXPlatformNodeBase::kEmbeddedCharacter));
     size_t character_index = 0;
     size_t hypertext_index = 0;
     while (hypertext_index < ia2_hypertext.length()) {
       if (ia2_hypertext[hypertext_index] !=
-          ui::AXPlatformNodeBase::kEmbeddedCharacter) {
+          AXPlatformNodeBase::kEmbeddedCharacter) {
         ++character_index;
         ++hypertext_index;
         continue;
@@ -555,11 +545,11 @@
   dict->Set("ia2_hypertext", base::WideToUTF16(ia2_hypertext));
 }
 
-void AccessibilityTreeFormatterWin::AddIA2TableProperties(
+void AXTreeFormatterWin::AddIA2TableProperties(
     const Microsoft::WRL::ComPtr<IAccessible> node,
     base::Value::Dict* dict) const {
   Microsoft::WRL::ComPtr<IAccessibleTable> ia2table;
-  if (S_OK != ui::IA2QueryInterface<IAccessibleTable>(node.Get(), &ia2table))
+  if (S_OK != IA2QueryInterface<IAccessibleTable>(node.Get(), &ia2table))
     return;  // No IA2Text, we are finished with this node.
 
   LONG table_rows;
@@ -594,11 +584,11 @@
   return related_accessibles_string + u">";
 }
 
-void AccessibilityTreeFormatterWin::AddIA2TableCellProperties(
+void AXTreeFormatterWin::AddIA2TableCellProperties(
     const Microsoft::WRL::ComPtr<IAccessible> node,
     base::Value::Dict* dict) const {
   Microsoft::WRL::ComPtr<IAccessibleTableCell> ia2cell;
-  if (S_OK != ui::IA2QueryInterface<IAccessibleTableCell>(node.Get(), &ia2cell))
+  if (S_OK != IA2QueryInterface<IAccessibleTableCell>(node.Get(), &ia2cell))
     return;  // No IA2Text, we are finished with this node.
 
   LONG column_index;
@@ -634,12 +624,12 @@
   }
 }
 
-void AccessibilityTreeFormatterWin::AddIA2TextProperties(
+void AXTreeFormatterWin::AddIA2TextProperties(
     const Microsoft::WRL::ComPtr<IAccessible> node,
     base::Value::Dict* dict) const {
   Microsoft::WRL::ComPtr<IAccessibleText> ia2text;
 
-  if (S_OK != ui::IA2QueryInterface<IAccessibleText>(node.Get(), &ia2text))
+  if (S_OK != IA2QueryInterface<IAccessibleText>(node.Get(), &ia2text))
     return;
 
   LONG n_characters;
@@ -702,11 +692,11 @@
   dict->Set("text_attributes", std::move(text_attributes));
 }
 
-void AccessibilityTreeFormatterWin::AddIA2ValueProperties(
+void AXTreeFormatterWin::AddIA2ValueProperties(
     const Microsoft::WRL::ComPtr<IAccessible> node,
     base::Value::Dict* dict) const {
   Microsoft::WRL::ComPtr<IAccessibleValue> ia2value;
-  if (S_OK != ui::IA2QueryInterface<IAccessibleValue>(node.Get(), &ia2value))
+  if (S_OK != IA2QueryInterface<IAccessibleValue>(node.Get(), &ia2value))
     return;  // No IA2Value, we are finished with this node.
 
   base::win::ScopedVariant current_value;
@@ -728,7 +718,7 @@
   }
 }
 
-std::string AccessibilityTreeFormatterWin::ProcessTreeForOutput(
+std::string AXTreeFormatterWin::ProcessTreeForOutput(
     const base::Value::Dict& dict) const {
   std::string line;
 
@@ -779,15 +769,15 @@
   return line;
 }
 
-Microsoft::WRL::ComPtr<IAccessible>
-AccessibilityTreeFormatterWin::FindActiveDocument(IAccessible* root) const {
-  for (const ui::MSAAChild& child : ui::MSAAChildren(root)) {
+Microsoft::WRL::ComPtr<IAccessible> AXTreeFormatterWin::FindActiveDocument(
+    IAccessible* root) const {
+  for (const MSAAChild& child : MSAAChildren(root)) {
     IAccessible* ia = child.AsIAccessible();
     if (!ia)
       continue;
 
     Microsoft::WRL::ComPtr<IAccessible2> ia2;
-    if (FAILED(ui::IA2QueryInterface<IAccessible2>(ia, &ia2)))
+    if (FAILED(IA2QueryInterface<IAccessible2>(ia, &ia2)))
       continue;  // No IA2, we are finished with this node.
 
     LONG role = 0;
@@ -821,4 +811,4 @@
   return nullptr;
 }
 
-}  // namespace content
+}  // namespace ui
diff --git a/content/browser/accessibility/accessibility_tree_formatter_win.h b/ui/accessibility/platform/inspect/ax_tree_formatter_win.h
similarity index 78%
rename from content/browser/accessibility/accessibility_tree_formatter_win.h
rename to ui/accessibility/platform/inspect/ax_tree_formatter_win.h
index ff774f4..fe10e77 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_win.h
+++ b/ui/accessibility/platform/inspect/ax_tree_formatter_win.h
@@ -2,28 +2,27 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_WIN_H_
-#define CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_WIN_H_
+#ifndef UI_ACCESSIBILITY_PLATFORM_INSPECT_AX_TREE_FORMATTER_WIN_H_
+#define UI_ACCESSIBILITY_PLATFORM_INSPECT_AX_TREE_FORMATTER_WIN_H_
 
 #include <oleacc.h>
 #include <wrl/client.h>
 
-#include "content/common/content_export.h"
+#include "ui/accessibility/ax_export.h"
 #include "ui/accessibility/platform/inspect/ax_tree_formatter_base.h"
 
-namespace content {
+namespace ui {
 
-class CONTENT_EXPORT AccessibilityTreeFormatterWin
-    : public ui::AXTreeFormatterBase {
+class AX_EXPORT AXTreeFormatterWin : public AXTreeFormatterBase {
  public:
-  AccessibilityTreeFormatterWin();
-  ~AccessibilityTreeFormatterWin() override;
+  AXTreeFormatterWin();
+  ~AXTreeFormatterWin() override;
 
-  base::Value::Dict BuildTree(ui::AXPlatformNodeDelegate* start) const override;
+  base::Value::Dict BuildTree(AXPlatformNodeDelegate* start) const override;
   base::Value::Dict BuildTreeForSelector(
       const AXTreeSelector& selector) const override;
 
-  base::Value::Dict BuildNode(ui::AXPlatformNodeDelegate* node) const override;
+  base::Value::Dict BuildNode(AXPlatformNodeDelegate* node) const override;
 
  protected:
   void AddDefaultFilters(
@@ -67,6 +66,6 @@
       IAccessible* root) const;
 };
 
-}  // namespace content
+}  // namespace ui
 
-#endif  // CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_WIN_H_
+#endif  // UI_ACCESSIBILITY_PLATFORM_INSPECT_AX_TREE_FORMATTER_WIN_H_
diff --git a/ui/base/ime/ash/BUILD.gn b/ui/base/ime/ash/BUILD.gn
index 8bfa0fb..93fa708 100644
--- a/ui/base/ime/ash/BUILD.gn
+++ b/ui/base/ime/ash/BUILD.gn
@@ -70,8 +70,8 @@
   deps = [
     ":ime_types",
     ":typing_session_manager",
-    "//ash/services/ime/public/mojom",
     "//build:branding_buildflags",
+    "//chromeos/ash/services/ime/public/mojom",
     "//chromeos/system",
     "//services/metrics/public/cpp:ukm_builders",
     "//third_party/icu",
diff --git a/ui/base/ime/ash/DEPS b/ui/base/ime/ash/DEPS
index 9cc91dd..0295c05 100644
--- a/ui/base/ime/ash/DEPS
+++ b/ui/base/ime/ash/DEPS
@@ -1,5 +1,5 @@
 include_rules = [
-  "+ash/services/ime/public/mojom",
+  "+chromeos/ash/services/ime/public/mojom",
   "+chromeos/ime",
   "+ui/chromeos/strings",
   "+ui/ozone/public",
diff --git a/ui/base/ime/ash/input_method_manager.h b/ui/base/ime/ash/input_method_manager.h
index 3314adbd..997c2b3 100644
--- a/ui/base/ime/ash/input_method_manager.h
+++ b/ui/base/ime/ash/input_method_manager.h
@@ -12,9 +12,9 @@
 #include <string>
 #include <vector>
 
-#include "ash/services/ime/public/mojom/ime_service.mojom.h"
 #include "base/component_export.h"
 #include "base/memory/ref_counted.h"
+#include "chromeos/ash/services/ime/public/mojom/ime_service.mojom.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "ui/base/ime/ash/ime_keyset.h"
 #include "ui/base/ime/ash/input_method_descriptor.h"
diff --git a/ui/base/ime/ash/input_method_ukm.h b/ui/base/ime/ash/input_method_ukm.h
index 85a9c2a..5fb19d4 100644
--- a/ui/base/ime/ash/input_method_ukm.h
+++ b/ui/base/ime/ash/input_method_ukm.h
@@ -5,8 +5,8 @@
 #ifndef UI_BASE_IME_ASH_INPUT_METHOD_UKM_H_
 #define UI_BASE_IME_ASH_INPUT_METHOD_UKM_H_
 
-#include "ash/services/ime/public/mojom/input_method_host.mojom-shared.h"
 #include "base/component_export.h"
+#include "chromeos/ash/services/ime/public/mojom/input_method_host.mojom-shared.h"
 #include "services/metrics/public/cpp/ukm_source_id.h"
 #include "ui/base/ime/text_input_type.h"
 
diff --git a/ui/compositor/test/in_process_context_factory.cc b/ui/compositor/test/in_process_context_factory.cc
index ccc26b7..89d47613 100644
--- a/ui/compositor/test/in_process_context_factory.cc
+++ b/ui/compositor/test/in_process_context_factory.cc
@@ -211,7 +211,7 @@
   if (!shared_worker_context_provider_ || shared_worker_context_provider_lost) {
     shared_worker_context_provider_ = InProcessContextProvider::CreateOffscreen(
         &gpu_memory_buffer_manager_, &image_factory_, /*is_worker=*/true);
-    auto result = shared_worker_context_provider_->BindToCurrentThread();
+    auto result = shared_worker_context_provider_->BindToCurrentSequence();
     if (result != gpu::ContextResult::kSuccess)
       shared_worker_context_provider_ = nullptr;
   }
@@ -283,7 +283,7 @@
 
   shared_main_thread_contexts_ = InProcessContextProvider::CreateOffscreen(
       &gpu_memory_buffer_manager_, &image_factory_, /*is_worker=*/false);
-  auto result = shared_main_thread_contexts_->BindToCurrentThread();
+  auto result = shared_main_thread_contexts_->BindToCurrentSequence();
   if (result != gpu::ContextResult::kSuccess)
     shared_main_thread_contexts_.reset();
 
diff --git a/ui/compositor/test/in_process_context_provider.cc b/ui/compositor/test/in_process_context_provider.cc
index 25a147c..f1d4a44 100644
--- a/ui/compositor/test/in_process_context_provider.cc
+++ b/ui/compositor/test/in_process_context_provider.cc
@@ -77,7 +77,7 @@
   base::RefCountedThreadSafe<InProcessContextProvider>::Release();
 }
 
-gpu::ContextResult InProcessContextProvider::BindToCurrentThread() {
+gpu::ContextResult InProcessContextProvider::BindToCurrentSequence() {
   // This is called on the thread the context will be used.
   DCHECK(context_thread_checker_.CalledOnValidThread());
 
diff --git a/ui/compositor/test/in_process_context_provider.h b/ui/compositor/test/in_process_context_provider.h
index 3f443f2..bda0568b 100644
--- a/ui/compositor/test/in_process_context_provider.h
+++ b/ui/compositor/test/in_process_context_provider.h
@@ -56,7 +56,7 @@
   // viz::ContextProvider / viz::RasterContextProvider implementation.
   void AddRef() const override;
   void Release() const override;
-  gpu::ContextResult BindToCurrentThread() override;
+  gpu::ContextResult BindToCurrentSequence() override;
   const gpu::Capabilities& ContextCapabilities() const override;
   const gpu::GpuFeatureInfo& GetGpuFeatureInfo() const override;
   gpu::gles2::GLES2Interface* ContextGL() override;
diff --git a/ui/file_manager/file_manager/common/js/dom_utils.ts b/ui/file_manager/file_manager/common/js/dom_utils.ts
new file mode 100644
index 0000000..d57efd9
--- /dev/null
+++ b/ui/file_manager/file_manager/common/js/dom_utils.ts
@@ -0,0 +1,39 @@
+// 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.
+
+/**
+ * Function to be used as event listener for `mouseenter`, it sets the `title`
+ * attribute in the event's element target, when the text content is clipped due
+ * to CSS overflow, as in showing `...`.
+ *
+ * NOTE: This should be used with `mouseenter` because this event triggers less
+ * frequent than `mouseover` and `mouseenter` doesn't bubble from the children
+ * element to the listener (see mouseenter on MDN for more details).
+ */
+export function mouseEnterMaybeShowTooltip(event: MouseEvent) {
+  const target = event.composedPath()[0] as HTMLElement;
+  if (!target) {
+    return;
+  }
+  maybeShowTooltip(target, target.innerText);
+}
+
+/**
+ * Sets the `title` attribute in the event's element target, when the text
+ * content is clipped due to CSS overflow, as in showing `...`.
+ */
+export function maybeShowTooltip(target: HTMLElement, title: string) {
+  if (hasOverflowEllipsis(target)) {
+    target.setAttribute('title', title);
+  } else {
+    target.removeAttribute('title');
+  }
+}
+
+/**
+ * Whether the text content is clipped due to CSS overflow, as in showing `...`.
+ */
+export function hasOverflowEllipsis(element: HTMLElement) {
+  return element.offsetWidth < element.scrollWidth;
+}
diff --git a/ui/file_manager/file_manager/foreground/js/file_tasks.js b/ui/file_manager/file_manager/foreground/js/file_tasks.js
index 5aa92ec..c285836 100644
--- a/ui/file_manager/file_manager/foreground/js/file_tasks.js
+++ b/ui/file_manager/file_manager/foreground/js/file_tasks.js
@@ -53,7 +53,7 @@
    * @param {?FileTransferController} fileTransferController
    * @param {!Array<!Entry>} entries
    * @param {!Array<?string>} mimeTypes
-   * @param {!Array<!chrome.fileManagerPrivate.FileTask>} tasks
+   * @param {!chrome.fileManagerPrivate.ResultingTasks} resultingTasks
    * @param {?chrome.fileManagerPrivate.FileTask} defaultTask
    * @param {!TaskHistory} taskHistory
    * @param {!NamingController} namingController
@@ -62,8 +62,8 @@
    */
   constructor(
       volumeManager, metadataModel, directoryModel, ui, fileTransferController,
-      entries, mimeTypes, tasks, defaultTask, taskHistory, namingController,
-      crostini, progressCenter) {
+      entries, mimeTypes, resultingTasks, defaultTask, taskHistory,
+      namingController, crostini, progressCenter) {
     /** @private @const {!VolumeManager} */
     this.volumeManager_ = volumeManager;
 
@@ -85,8 +85,8 @@
     /** @private @const {!Array<?string>} */
     this.mimeTypes_ = mimeTypes;
 
-    /** @private @const {!Array<!chrome.fileManagerPrivate.FileTask>} */
-    this.tasks_ = tasks;
+    /** @private @const {!chrome.fileManagerPrivate.ResultingTasks} */
+    this.resultingTasks_ = resultingTasks;
 
     /** @private @const {?chrome.fileManagerPrivate.FileTask} */
     this.defaultTask_ = defaultTask;
@@ -138,19 +138,18 @@
       volumeManager, metadataModel, directoryModel, ui, fileTransferController,
       entries, mimeTypes, taskHistory, namingController, crostini,
       progressCenter) {
-    /** @type {!Array<!chrome.fileManagerPrivate.FileTask>} */
-    let tasks = [];
+    /** @type {!chrome.fileManagerPrivate.ResultingTasks} */
+    let resultingTasks = {tasks: []};
 
     // Cannot use fake entries with getFileTasks.
     entries = entries.filter(e => !util.isFakeEntry(e));
     if (entries.length !== 0) {
-      const resultingTasks = await new Promise(
+      resultingTasks = await new Promise(
           fulfill => chrome.fileManagerPrivate.getFileTasks(entries, fulfill));
       if (!resultingTasks || !resultingTasks.tasks) {
         throw new Error(
             'Cannot get file tasks: ' + chrome.runtime.lastError.message);
       }
-      tasks = resultingTasks.tasks;
     }
 
     // Linux package installation is currently only supported for a single file
@@ -163,19 +162,20 @@
           crostini.canSharePath(
               constants.DEFAULT_CROSTINI_VM, entries[0],
               false /* persist */))) {
-      tasks = tasks.filter(
+      resultingTasks.tasks = resultingTasks.tasks.filter(
           task => !util.descriptorEqual(
               task.descriptor,
               FileTasks.INSTALL_LINUX_PACKAGE_TASK_DESCRIPTOR));
     }
 
-    tasks = FileTasks.annotateTasks_(tasks, entries);
+    resultingTasks.tasks =
+        FileTasks.annotateTasks_(resultingTasks.tasks, entries);
 
-    const defaultTask = FileTasks.getDefaultTask(tasks, taskHistory);
+    const defaultTask = FileTasks.getDefaultTask(resultingTasks, taskHistory);
 
     return new FileTasks(
         volumeManager, metadataModel, directoryModel, ui,
-        fileTransferController, entries, mimeTypes, tasks, defaultTask,
+        fileTransferController, entries, mimeTypes, resultingTasks, defaultTask,
         taskHistory, namingController, crostini, progressCenter);
   }
 
@@ -184,7 +184,7 @@
    * @return {!Array<!chrome.fileManagerPrivate.FileTask>}
    */
   getTaskItems() {
-    return this.tasks_;
+    return this.resultingTasks_.tasks;
   }
 
   /**
@@ -192,7 +192,15 @@
    * @return {!Array<!chrome.fileManagerPrivate.FileTask>}
    */
   getOpenTaskItems() {
-    return this.tasks_.filter(FileTasks.isOpenTask);
+    return this.resultingTasks_.tasks.filter(FileTasks.isOpenTask);
+  }
+
+  /**
+   * Gets the policy default handler status.
+   * @return {!chrome.fileManagerPrivate.PolicyDefaultHandlerStatus|undefined}
+   */
+  getPolicyDefaultHandlerStatus() {
+    return this.resultingTasks_.policyDefaultHandlerStatus;
   }
 
   /**
@@ -571,13 +579,24 @@
   executeDefaultInternal_(opt_callback) {
     const callback = opt_callback || ((arg1, arg2) => {});
 
-    if (this.defaultTask_ !== null) {
+    if (this.defaultTask_) {
       this.executeInternal_(this.defaultTask_);
       callback(true, this.entries_);
       return;
     }
 
-    const nonGenericTasks = this.tasks_.filter(t => !t.isGenericFileHandler);
+    // If there's policy involved and |defaultTask_| is null, means that policy
+    // assignment was incorrect. We should not execute anything in this case.
+    if (this.getPolicyDefaultHandlerStatus()) {
+      assert(
+          this.getPolicyDefaultHandlerStatus() ===
+          chrome.fileManagerPrivate.PolicyDefaultHandlerStatus
+              .INCORRECT_ASSIGNMENT);
+      return;
+    }
+
+    const nonGenericTasks =
+        this.resultingTasks_.tasks.filter(t => !t.isGenericFileHandler);
     // If there is only one task that is not a generic file handler, it should
     // be executed as a default task. If there are multiple tasks that are not
     // generic file handlers, and none of them are considered as default, we
@@ -1049,13 +1068,7 @@
    * @public
    */
   display(openCombobutton) {
-    const openTasks = [];
-    for (const task of this.tasks_) {
-      if (FileTasks.isOpenTask(task)) {
-        openTasks.push(task);
-      }
-    }
-    this.updateOpenComboButton_(openCombobutton, openTasks);
+    this.updateOpenComboButton_(openCombobutton, this.getOpenTaskItems());
   }
 
   /**
@@ -1089,8 +1102,7 @@
     // (including defaultTask). If only one generic task is available, we
     // also show it in the context menu.
     const items = this.createItems_(tasks);
-    if (items.length > 1 ||
-        (items.length === 1 && this.defaultTask_ === null)) {
+    if (items.length > 1 || (items.length === 1 && !this.defaultTask_)) {
       for (const item of items) {
         combobutton.addDropDownItem(item);
       }
@@ -1101,9 +1113,20 @@
         combobutton.addSeparator();
         const changeDefaultMenuItem = combobutton.addDropDownItem({
           type: FileTasks.TaskMenuButtonItemType.ChangeDefaultTask,
-          label: loadTimeData.getString('CHANGE_DEFAULT_MENU_ITEM'),
+          label: str('CHANGE_DEFAULT_MENU_ITEM'),
         });
         changeDefaultMenuItem.classList.add('change-default');
+
+        // Disables CHANGE_DEFAULT button if default has been set by policy.
+        if (this.getPolicyDefaultHandlerStatus()) {
+          // |defaultTask_| exists, thus |policyDefaultHandlerStatus| cannot be
+          // INCORRECT_ASSIGNMENT.
+          assert(
+              this.getPolicyDefaultHandlerStatus() ===
+              chrome.fileManagerPrivate.PolicyDefaultHandlerStatus
+                  .DEFAULT_HANDLER_ASSIGNED_BY_POLICY);
+          changeDefaultMenuItem.disabled = true;
+        }
       }
     }
   }
@@ -1214,13 +1237,23 @@
    * Gets the default task from tasks. In case there is no such task (i.e. all
    * tasks are generic file handlers), then return null.
    *
-   * @param {!Array<!chrome.fileManagerPrivate.FileTask>} tasks The list of
-   *     tasks from where to choose the default task.
+   * @param {!chrome.fileManagerPrivate.ResultingTasks} resultingTasks The list
+   *     of tasks from where to choose the default task.
    * @param {!TaskHistory} taskHistory
    * @return {?chrome.fileManagerPrivate.FileTask} the default task, or null if
    *     no default task found.
    */
-  static getDefaultTask(tasks, taskHistory) {
+  static getDefaultTask(resultingTasks, taskHistory) {
+    const {tasks, policyDefaultHandlerStatus} = resultingTasks;
+
+    // If policy assignment is incorrect, then no default should be set.
+    if (policyDefaultHandlerStatus &&
+        policyDefaultHandlerStatus ===
+            chrome.fileManagerPrivate.PolicyDefaultHandlerStatus
+                .INCORRECT_ASSIGNMENT) {
+      return null;
+    }
+
     // 1. Default app set for MIME or file extension by user, or built-in app.
     for (const task of tasks) {
       if (task.isDefault) {
@@ -1228,6 +1261,14 @@
       }
     }
 
+    // If policy assignment is marked as correct, then by this moment we
+    // should've already found the default.
+    assert(
+        !(policyDefaultHandlerStatus &&
+          policyDefaultHandlerStatus ===
+              chrome.fileManagerPrivate.PolicyDefaultHandlerStatus
+                  .DEFAULT_HANDLER_ASSIGNED_BY_POLICY));
+
     const nonGenericTasks = tasks.filter(t => !t.isGenericFileHandler);
     if (nonGenericTasks.length === 0) {
       return null;
diff --git a/ui/file_manager/file_manager/foreground/js/task_controller.js b/ui/file_manager/file_manager/foreground/js/task_controller.js
index 09af11a..7ef1229 100644
--- a/ui/file_manager/file_manager/foreground/js/task_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/task_controller.js
@@ -360,11 +360,11 @@
       // Compare entries while ignoring changes inside directories.
       if (!util.isSameEntries(this.lastSelectedEntries_, selection.entries)) {
         // Update the context menu if selection changed.
-        this.updateContextMenuTaskItems_([]);
+        this.updateContextMenuTaskItems_({tasks: []});
       }
     } else {
       // Update context menu.
-      this.updateContextMenuTaskItems_([]);
+      this.updateContextMenuTaskItems_({tasks: []});
     }
     this.lastSelectedEntries_ = selection.entries;
   }
@@ -409,7 +409,9 @@
       // Update the DOM.
       tasks.display(this.ui_.taskMenuButton);
       const openTaskItems = tasks.getOpenTaskItems();
-      this.updateContextMenuTaskItems_(openTaskItems);
+      const policyDefaultHandlerStatus = tasks.getPolicyDefaultHandlerStatus();
+      this.updateContextMenuTaskItems_(
+          {tasks: openTaskItems, policyDefaultHandlerStatus});
       if (window.IN_TEST) {
         this.ui_.taskMenuButton.toggleAttribute('get-tasks-completed', true);
       }
@@ -478,44 +480,48 @@
   /**
    * Updates tasks menu item to match passed task items.
    *
-   * @param {!Array<!chrome.fileManagerPrivate.FileTask>} openTasks List of OPEN
+   * @param {!chrome.fileManagerPrivate.ResultingTasks} openTasks List of OPEN
    *     tasks.
    * @private
    */
   updateContextMenuTaskItems_(openTasks) {
-    const defaultTask = FileTasks.getDefaultTask(openTasks, this.taskHistory_);
-    if (defaultTask) {
-      const menuItem = this.ui_.defaultTaskMenuItem;
-      /**
-       * Menu icon can be controlled by either `iconEndImage` or
-       * `iconEndFileType`, since the default task menu item DOM is shared,
-       * before updating it, we should remove the previous one, e.g. reset both
-       * `iconEndImage` and `iconEndFileType`.
-       */
-      menuItem.iconEndImage = '';
-      menuItem.removeIconEndFileType();
+    const taskCount = openTasks.tasks.length;
+    if (taskCount > 0) {
+      const defaultTask =
+          FileTasks.getDefaultTask(openTasks, this.taskHistory_);
+      if (defaultTask) {
+        const menuItem = this.ui_.defaultTaskMenuItem;
+        /**
+         * Menu icon can be controlled by either `iconEndImage` or
+         * `iconEndFileType`, since the default task menu item DOM is shared,
+         * before updating it, we should remove the previous one, e.g. reset
+         * both `iconEndImage` and `iconEndFileType`.
+         */
+        menuItem.iconEndImage = '';
+        menuItem.removeIconEndFileType();
 
-      menuItem.setIconEndHidden(false);
-      if (defaultTask.iconType) {
-        menuItem.iconEndFileType = defaultTask.iconType;
-      } else if (defaultTask.iconUrl) {
-        menuItem.iconEndImage = 'url(' + defaultTask.iconUrl + ')';
-      } else {
-        menuItem.setIconEndHidden(true);
+        menuItem.setIconEndHidden(false);
+        if (defaultTask.iconType) {
+          menuItem.iconEndFileType = defaultTask.iconType;
+        } else if (defaultTask.iconUrl) {
+          menuItem.iconEndImage = 'url(' + defaultTask.iconUrl + ')';
+        } else {
+          menuItem.setIconEndHidden(true);
+        }
+
+        menuItem.label = defaultTask.label || defaultTask.title;
+        menuItem.disabled = !!defaultTask.disabled;
+        menuItem.descriptor = defaultTask.descriptor;
       }
 
-      menuItem.label = defaultTask.label || defaultTask.title;
-      menuItem.disabled = !!defaultTask.disabled;
-      menuItem.descriptor = defaultTask.descriptor;
+      this.canExecuteDefaultTask_ = defaultTask != null;
+      this.defaultTaskCommand_.canExecuteChange(this.ui_.listContainer.element);
     }
 
-    this.canExecuteDefaultTask_ = defaultTask != null;
-    this.defaultTaskCommand_.canExecuteChange(this.ui_.listContainer.element);
-
-    this.canExecuteOpenActions_ = openTasks.length > 1;
+    this.canExecuteOpenActions_ = taskCount > 1;
     this.openWithCommand_.canExecuteChange(this.ui_.listContainer.element);
 
-    this.ui_.tasksSeparator.hidden = openTasks.length === 0;
+    this.ui_.tasksSeparator.hidden = taskCount === 0;
   }
 
   /**
diff --git a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js
index 1aad879..9d16fe7 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js
@@ -4,10 +4,8 @@
 
 import {assert, assertNotReached} from 'chrome://resources/js/assert.js';
 import {dispatchSimpleEvent, getPropertyDescriptor, PropertyKind} from 'chrome://resources/js/cr.m.js';
-import {Command} from './command.js';
-import {contextMenuHandler} from './context_menu_handler.js';
-import {Menu} from './menu.js';
 
+import {maybeShowTooltip} from '../../../common/js/dom_utils.js';
 import {FileType} from '../../../common/js/file_type.js';
 import {vmTypeToIconName} from '../../../common/js/icon_util.js';
 import {metrics} from '../../../common/js/metrics.js';
@@ -23,6 +21,9 @@
 import {MetadataModel} from '../metadata/metadata_model.js';
 import {NavigationListModel, NavigationModelAndroidAppItem, NavigationModelFakeItem, NavigationModelItem, NavigationModelItemType, NavigationModelShortcutItem, NavigationModelVolumeItem, NavigationSection} from '../navigation_list_model.js';
 
+import {Command} from './command.js';
+import {contextMenuHandler} from './context_menu_handler.js';
+import {Menu} from './menu.js';
 import {Tree, TreeItem} from './tree.js';
 
 // Namespace
@@ -2017,6 +2018,9 @@
       }
     });
 
+    this.addEventListener(
+        'mouseover', this.onMouseOver_.bind(this), {passive: true});
+
     this.privateOnDirectoryChangedBound_ =
         this.onDirectoryContentChanged_.bind(this);
     chrome.fileManagerPrivate.onDirectoryChanged.addListener(
@@ -2030,6 +2034,27 @@
     this.fakeEntriesVisible_ = fakeEntriesVisible;
   }
 
+  onMouseOver_(event) {
+    this.maybeShowToolTip(event);
+  }
+
+  maybeShowToolTip(event) {
+    const target = event.composedPath()[0];
+    if (!target) {
+      return;
+    }
+    if (!(target.classList.contains('tree-row') &&
+          target.parentElement?.label)) {
+      return;
+    }
+    const labelElement = target.querySelector('.label');
+    if (!labelElement) {
+      return;
+    }
+
+    maybeShowTooltip(labelElement, target.parentElement.label);
+  }
+
   /**
    * Updates and selects new directory.
    * @param {!DirectoryEntry} parentDirectory Parent directory of new directory.
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_grid.js b/ui/file_manager/file_manager/foreground/js/ui/file_grid.js
index 155a34e..b285377 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/file_grid.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/file_grid.js
@@ -7,6 +7,7 @@
 import {isRTL} from 'chrome://resources/js/util.js';
 
 import {AsyncUtil} from '../../../common/js/async_util.js';
+import {maybeShowTooltip} from '../../../common/js/dom_utils.js';
 import {FileType} from '../../../common/js/file_type.js';
 import {util} from '../../../common/js/util.js';
 import {FilesAppEntry} from '../../../externs/files_app_entry_interfaces.js';
@@ -158,6 +159,32 @@
     self.paddingStart_ =
         parseFloat(isRTL() ? style.paddingRight : style.paddingLeft);
     self.paddingTop_ = parseFloat(style.paddingTop);
+
+    self.addEventListener(
+        'mouseover', self.onMouseOver_.bind(self), {passive: true});
+  }
+
+  onMouseOver_(event) {
+    this.maybeShowToolTip(event);
+  }
+
+  maybeShowToolTip(event) {
+    let target = null;
+    for (const el of event.composedPath()) {
+      if (el.classList?.contains('thumbnail-item')) {
+        target = el;
+        break;
+      }
+    }
+    if (!target) {
+      return;
+    }
+    const labelElement = target.querySelector('.filename-label');
+    if (!labelElement) {
+      return;
+    }
+
+    maybeShowTooltip(labelElement, labelElement.innerText);
   }
 
   /**
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_metadata_formatter.js b/ui/file_manager/file_manager/foreground/js/ui/file_metadata_formatter.js
index 2570b60..be2e33b 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/file_metadata_formatter.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/file_metadata_formatter.js
@@ -27,16 +27,30 @@
    */
   setDateTimeFormat(use12hourClock) {
     const locale = util.getCurrentLocaleOrDefault();
-    this.timeFormatter_ = new Intl.DateTimeFormat(
-        locale, {hour: 'numeric', minute: 'numeric', hour12: use12hourClock});
-    this.dateFormatter_ = new Intl.DateTimeFormat(locale, {
+    const options = {
+      hour: 'numeric',
+      minute: 'numeric',
+    };
+    if (use12hourClock) {
+      options['hour12'] = true;
+    } else {
+      options['hourCycle'] = 'h23';
+    }
+    this.timeFormatter_ = new Intl.DateTimeFormat(locale, options);
+    const dateOptions = {
       year: 'numeric',
       month: 'short',
       day: 'numeric',
       hour: 'numeric',
       minute: 'numeric',
-      hour12: use12hourClock,
-    });
+    };
+    if (use12hourClock) {
+      dateOptions['hour12'] = true;
+    } else {
+      dateOptions['hourCycle'] = 'h23';
+    }
+
+    this.dateFormatter_ = new Intl.DateTimeFormat(locale, dateOptions);
     dispatchSimpleEvent(this, 'date-time-format-changed');
   }
 
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_table.js b/ui/file_manager/file_manager/foreground/js/ui/file_table.js
index 53745968..8ad7bf1 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/file_table.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/file_table.js
@@ -6,6 +6,7 @@
 import {dispatchSimpleEvent} from 'chrome://resources/js/cr.m.js';
 
 import {AsyncUtil} from '../../../common/js/async_util.js';
+import {maybeShowTooltip} from '../../../common/js/dom_utils.js';
 import {FileType} from '../../../common/js/file_type.js';
 import {str, strf, util} from '../../../common/js/util.js';
 import {FilesAppEntry} from '../../../externs/files_app_entry_interfaces.js';
@@ -502,6 +503,29 @@
     }.bind(self), true);
     self.list.shouldStartDragSelection =
         self.shouldStartDragSelection_.bind(self);
+
+    self.list.addEventListener(
+        'mouseover', self.onMouseOver_.bind(self), {passive: true});
+  }
+
+  onMouseOver_(event) {
+    this.maybeShowToolTip(event);
+  }
+
+  maybeShowToolTip(event) {
+    const target = event.composedPath()[0];
+    if (!target) {
+      return;
+    }
+    if (!target.classList.contains('detail-name')) {
+      return;
+    }
+    const labelElement = target.querySelector('.filename-label');
+    if (!labelElement) {
+      return;
+    }
+
+    maybeShowTooltip(labelElement, labelElement.innerText);
   }
 
   /**
diff --git a/ui/file_manager/file_manager/widgets/xf_breadcrumb.ts b/ui/file_manager/file_manager/widgets/xf_breadcrumb.ts
index 41ecba29..b7f260a 100644
--- a/ui/file_manager/file_manager/widgets/xf_breadcrumb.ts
+++ b/ui/file_manager/file_manager/widgets/xf_breadcrumb.ts
@@ -4,6 +4,8 @@
 
 import {CrActionMenuElement} from 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
 
+import {mouseEnterMaybeShowTooltip} from '../common/js/dom_utils.js';
+
 import {getTemplate} from './xf_breadcrumb.html.js';
 
 /**
@@ -35,6 +37,12 @@
     this.addEventListener('tabkeyclose', this.onTabkeyClose_.bind(this));
     this.addEventListener('close', this.closeMenu_.bind(this));
     this.addEventListener('blur', this.closeMenu_.bind(this));
+    const buttons =
+        Array.from(this.shadowRoot!.querySelectorAll('button:not([elider])')) as
+        HTMLButtonElement[];
+    buttons.forEach(button => {
+      button.addEventListener('mouseenter', mouseEnterMaybeShowTooltip);
+    });
   }
 
   /** Gets parts.  */
@@ -123,6 +131,9 @@
 
     const menu = this.shadowRoot!.querySelector('cr-action-menu')!;
     menu.innerHTML = elidedParts;
+    menu.querySelectorAll('button').forEach(button => {
+      button.addEventListener('mouseenter', mouseEnterMaybeShowTooltip);
+    });
 
     (elider.previousElementSibling as HTMLButtonElement).hidden = false;
     elider.hidden = false;
@@ -132,7 +143,7 @@
    * Returns the breadcrumb buttons: they contain the current path ordered by
    * its parts, which are stored in the <button>.textContent.
    */
-  private getBreadcrumbButtons_(): HTMLButtonElement[] {
+  getBreadcrumbButtons(): HTMLButtonElement[] {
     const parts = this.shadowRoot!.querySelectorAll<HTMLButtonElement>(
         'button[id]:not([hidden])')!;
     if (this.parts_.length <= 4) {
@@ -146,36 +157,6 @@
   }
 
   /**
-   * Returns the visible buttons rendered CSS overflow: ellipsis that have no
-   * 'has-tooltip' attribute.
-   *
-   * Note: call in a requestAnimationFrame() to avoid a style resolve.
-   *
-   * @return  buttons Callers can set the tool tip attribute on the returned
-   *     buttons.
-   */
-  getEllipsisButtons(): HTMLButtonElement[] {
-    return this.getBreadcrumbButtons_().filter(button => {
-      if (!button.hasAttribute('has-tooltip') && button.offsetWidth) {
-        return button.offsetWidth < button.scrollWidth;
-      }
-      return false;
-    });
-  }
-
-  /**
-   * Returns breadcrumb buttons that have a 'has-tooltip' attribute. Note the
-   * elider button is excluded since it has an i18n aria-label.
-   *
-   * @return buttons Caller could remove the tool tip event listeners from the
-   *     returned buttons.
-   */
-  getToolTipButtons(): HTMLButtonElement[] {
-    const hasToolTip = 'button:not([elider])[has-tooltip]';
-    return Array.from(this.shadowRoot!.querySelectorAll(hasToolTip));
-  }
-
-  /**
    * Handles 'click' events.
    *
    * Emits the `BREADCRUMB_CLICKED` event when a breadcumb button is clicked
@@ -196,7 +177,7 @@
     }
 
     if (element instanceof HTMLButtonElement) {
-      const parts = this.getBreadcrumbButtons_();
+      const parts = this.getBreadcrumbButtons();
       this.dispatchEvent(new CustomEvent(BREADCRUMB_CLICKED, {
         bubbles: true,
         composed: true,
diff --git a/ui/file_manager/file_manager/widgets/xf_breadcrumb_unittest.ts b/ui/file_manager/file_manager/widgets/xf_breadcrumb_unittest.ts
index a749d870..a54d252 100644
--- a/ui/file_manager/file_manager/widgets/xf_breadcrumb_unittest.ts
+++ b/ui/file_manager/file_manager/widgets/xf_breadcrumb_unittest.ts
@@ -5,6 +5,7 @@
 import {assert} from 'chrome://resources/js/assert_ts.js';
 import {assertEquals, assertFalse, assertGE, assertGT, assertNotEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
 
+import {hasOverflowEllipsis} from '../common/js/dom_utils.js';
 import {waitUntil} from '../common/js/test_error_reporting.js';
 
 import {BREADCRUMB_CLICKED, BreadcrumbClickedEvent, XfBreadcrumb} from './xf_breadcrumb.js';
@@ -175,6 +176,21 @@
   return waitUntil(() => element.getAttribute('path')! === path);
 }
 
+function simulateMouseEnter(element: HTMLElement) {
+  const ev = new MouseEvent('mouseenter', {
+    view: window,
+    bubbles: true,
+    cancelable: true,
+  });
+
+  element.dispatchEvent(ev);
+}
+
+/** Returns the visible buttons rendered with CSS overflow ellipsis.  */
+function getEllipsisButtons(breadcrumb: XfBreadcrumb): HTMLButtonElement[] {
+  return breadcrumb.getBreadcrumbButtons().filter(hasOverflowEllipsis);
+}
+
 /**
  * Tests rendering an empty path.
  */
@@ -686,51 +702,48 @@
 
 /**
  * Tests that wide text path components are rendered elided with ellipsis ...
- * an opportunity for adding a tooltip.
+ * and hovering over the button sets the `title` attribute which is used by the
+ * browser to render the native tooltip.
  */
 export async function testBreadcrumbPartPartsEllipsisElide(done: () => void) {
   const element = getBreadcrumb();
 
   // Set path.
-  await setAndWaitPath('A/VERYVERYVERYVERYWIDEPATHPART');
+  await setAndWaitPath('VERYVERYVERYVERYWIDEPATHPART/A');
 
   // clang-format off
   const expect = element.path +
-      ' 1: display:block id=first text=[A]' +
+      ' 1: display:block id=first text=[VERYVERYVERYVERYWIDEPATHPART]' +
       ' 2: display:none elider[aria-expanded=false,aria-haspopup,aria-label,hidden]' +
       ' 3: display:none id=second hidden' +
       ' 4: display:none id=third hidden' +
-      ' 5: display:block id=fourth text=[VERYVERYVERYVERYWIDEPATHPART]';
+      ' 5: display:block id=fourth text=[A]';
   // clang-format on
 
   const path = element.parts.join('/');
   assertEquals(expect, path + ' ' + getBreadcrumbButtonState());
 
   // The wide part should render its text with ellipsis.
-  let ellipsis = element.getEllipsisButtons();
+  const ellipsis = getEllipsisButtons(element);
   const parts = element.parts;
   assert(ellipsis[0]);
-  assert(parts[1]);
+  assert(parts[0]);
 
   assertEquals(1, ellipsis.length);
-  assertEquals(element.parts[1], ellipsis[0].textContent);
+  const button = ellipsis[0];
+  assertEquals(element.parts[0], button.textContent);
 
-  // Add has-tooltip attribute to this ellipsis button.
-  ellipsis[0].setAttribute('has-tooltip', '');
-  const tooltip = element.getToolTipButtons();
-  assert(tooltip[0]);
-  assertEquals(ellipsis[0], tooltip[0]);
-
-  // getEllipsisButtons() should ignore [has-tooltip] buttons.
-  ellipsis = element.getEllipsisButtons();
-  assertEquals(0, ellipsis.length);
+  // Simulate the mouseenter that sets the title.
+  simulateMouseEnter(button);
+  await waitUntil(() => button.getAttribute('title')! === button.innerText);
 
   done();
 }
 
 /**
  * Tests that wide text path components in the drop-down menu are rendered
- * elided with ellipsis ... an opportunity for adding a tooltip.
+ * elided with ellipsis ... and hovering over the button sets the `title`
+ * attribute which is used by the browser to render the native tooltip.
  */
 export async function testBreadcrumbDropDownMenuPathPartsEllipsisElide(
     done: () => void) {
@@ -750,7 +763,6 @@
       ' 4: display:block id=third text=[C]' +
       ' 5: display:block id=fourth text=[D]';
   // clang-format on
-
   const path = element.parts.join('/');
   assertEquals(expect, path + ' ' + getBreadcrumbButtonState());
 
@@ -762,93 +774,15 @@
   assert(parts[2]);
 
   // The wide part button should render its text with ellipsis.
-  let ellipsis = element.getEllipsisButtons();
+  const ellipsis = getEllipsisButtons(element);
   assertEquals(1, ellipsis.length);
   assert(ellipsis[0]);
   assertEquals(parts[2], ellipsis[0].textContent);
 
-  // Add a has-tooltip attribute to the ellipsis button.
-  ellipsis[0].setAttribute('has-tooltip', '');
-  const tooltip = element.getToolTipButtons();
-  assertEquals(1, tooltip.length);
-  assert(tooltip[0]);
-  assertEquals(ellipsis[0], tooltip[0]);
-
-  // getEllipsisButtons() should ignore [has-tooltip] buttons.
-  ellipsis = element.getEllipsisButtons();
-  assertEquals(0, ellipsis.length);
-
-  done();
-}
-
-/**
- * Tests that breadcrumb getToolTipButtons() service returns all buttons that
- * have a [has-tooltip] attribute.
- */
-export async function testBreadcrumbButtonHasToolTipAttribute(
-    done: () => void) {
-  const element = getBreadcrumb();
-
-  // Set path.
-  await setAndWaitPath('A/B/C/D/E');
-
-  // Add a tool tip to the visible main buttons.
-  getVisibleBreadcrumbMainButtons().forEach((button) => {
-    button.setAttribute('has-tooltip', '');
-  });
-
-  // getToolTipButtons() should return those main buttons.
-  let tooltips = element.getToolTipButtons();
-
-  assertEquals(3, tooltips.length);
-  assert(tooltips[0]);
-  assert(tooltips[1]);
-  assert(tooltips[2]);
-  assertEquals('A', tooltips[0].textContent);
-  assertEquals('D', tooltips[1].textContent);
-  assertEquals('E', tooltips[2].textContent);
-
-  // Changing the path should clear all tool tips.
-  await setAndWaitPath('G/H/I/J/K');
-  assertEquals(0, element.getToolTipButtons().length);
-
-  // Add tool tips to the drop-down menu buttons.
-  getBreadcrumbMenuButtons().forEach((button) => {
-    button.setAttribute('has-tooltip', '');
-  });
-
-  // getToolTipButtons() should return those menu buttons.
-  tooltips = element.getToolTipButtons();
-  assertEquals(2, tooltips.length);
-  assert(tooltips[0]);
-  assert(tooltips[1]);
-  assertEquals('H', tooltips[0].textContent);
-  assertEquals('I', tooltips[1].textContent);
-
-  // Note: tool tips can be enabled for the elider button.
-  const elider = getBreadcrumbEliderButton();
-  elider.setAttribute('has-tooltip', '');
-
-  // But getToolTipButtons() must exclude the elider (i18n).
-  tooltips = element.getToolTipButtons();
-  assertEquals(2, tooltips.length);
-  assert(tooltips[0]);
-  assert(tooltips[1]);
-  assertEquals('H', tooltips[0].textContent);
-  assertEquals('I', tooltips[1].textContent);
-
-  // And changing path should not clear its tool tip (i18n).
-  await setAndWaitPath('since/the/elider/has/an/i18n/tooltip/aria-label');
-  assertEquals(0, element.getToolTipButtons().length);
-  assertTrue(elider.hasAttribute('has-tooltip'));
-
-  // getEllipsisButtons() must exclude the elider button.
-  await setAndWaitPath(elider.getAttribute('aria-label')!);
-  const ellipsis = element.getEllipsisButtons();
-  assertEquals(getVisibleBreadcrumbMainButtons()[0], ellipsis[0]);
-  assertEquals(1, ellipsis.length);
-  assert(ellipsis[0]);
-  assertNotEquals(elider, ellipsis[0]);
+  // Simulate the mouseenter that sets the title.
+  const button = ellipsis[0];
+  simulateMouseEnter(button);
+  await waitUntil(() => button.getAttribute('title')! === button.innerText);
 
   done();
 }
diff --git a/ui/file_manager/file_names.gni b/ui/file_manager/file_names.gni
index e5323dc1..c2afddb 100644
--- a/ui/file_manager/file_names.gni
+++ b/ui/file_manager/file_names.gni
@@ -244,10 +244,15 @@
 # END: static_js_files.
 
 ts_files = [
+  # Common.
+  "file_manager/common/js/dom_utils.ts",
+
+  # Lib.
   "file_manager/lib/actions_producer.ts",
   "file_manager/lib/base_store.ts",
   "file_manager/lib/concurrency_models.ts",
 
+  # State.
   "file_manager/state/store.ts",
   "file_manager/state/reducers/root.ts",
   "file_manager/state/reducers/all_entries.ts",
@@ -255,10 +260,14 @@
   "file_manager/state/reducers/search.ts",
   "file_manager/state/actions.ts",
   "file_manager/state/file_key.ts",
-  "file_manager/widgets/xf_breadcrumb.ts",
-  "file_manager/widgets/xf_nudge.ts",
+
+  # Containers.
   "file_manager/containers/breadcrumb_container.ts",
   "file_manager/containers/nudge_container.ts",
+
+  # Widgets.
+  "file_manager/widgets/xf_breadcrumb.ts",
+  "file_manager/widgets/xf_nudge.ts",
   "file_manager/widgets/xf_dlp_restriction_details_dialog.ts",
 ]
 
diff --git a/ui/gl/BUILD.gn b/ui/gl/BUILD.gn
index 1cc665b..e2bc9ca7 100644
--- a/ui/gl/BUILD.gn
+++ b/ui/gl/BUILD.gn
@@ -241,6 +241,8 @@
 
     if (is_android) {
       sources += [
+        "android/egl_fence_utils.cc",
+        "android/egl_fence_utils.h",
         "gl_image_ahardwarebuffer.cc",
         "gl_image_ahardwarebuffer.h",
         "gl_surface_egl_surface_control.cc",
diff --git a/gpu/ipc/common/android/android_image_reader_utils.cc b/ui/gl/android/egl_fence_utils.cc
similarity index 94%
rename from gpu/ipc/common/android/android_image_reader_utils.cc
rename to ui/gl/android/egl_fence_utils.cc
index f709ed7..e6d4475 100644
--- a/gpu/ipc/common/android/android_image_reader_utils.cc
+++ b/ui/gl/android/egl_fence_utils.cc
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "gpu/ipc/common/android/android_image_reader_utils.h"
+#include "ui/gl/android/egl_fence_utils.h"
 
 #include "ui/gl/gl_fence_android_native_fence_sync.h"
 
-namespace gpu {
+namespace gl {
 
 base::ScopedFD CreateEglFenceAndExportFd() {
   std::unique_ptr<gl::GLFenceAndroidNativeFenceSync> android_native_fence =
@@ -62,4 +62,4 @@
   return true;
 }
 
-}  // namespace gpu
+}  // namespace gl
diff --git a/ui/gl/android/egl_fence_utils.h b/ui/gl/android/egl_fence_utils.h
new file mode 100644
index 0000000..10aa0f12
--- /dev/null
+++ b/ui/gl/android/egl_fence_utils.h
@@ -0,0 +1,21 @@
+// 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 UI_GL_ANDROID_EGL_FENCE_UTILS_H_
+#define UI_GL_ANDROID_EGL_FENCE_UTILS_H_
+
+#include "base/files/scoped_file.h"
+#include "ui/gl/gl_export.h"
+
+namespace gl {
+
+// Create and inserts an egl fence and exports a ScopedFD from it.
+GL_EXPORT base::ScopedFD CreateEglFenceAndExportFd();
+
+// Create and insert an EGL fence and imports the provided fence fd.
+GL_EXPORT bool InsertEglFenceAndWait(base::ScopedFD acquire_fence_fd);
+
+}  // namespace gl
+
+#endif  // UI_GL_ANDROID_EGL_FENCE_UTILS_H_
diff --git a/ui/views/controls/image_view_base.cc b/ui/views/controls/image_view_base.cc
index 46716b6..7764e41 100644
--- a/ui/views/controls/image_view_base.cc
+++ b/ui/views/controls/image_view_base.cc
@@ -40,7 +40,7 @@
   }
 
   node_data->role = ax::mojom::Role::kImage;
-  node_data->SetName(name);
+  node_data->SetNameChecked(name);
 }
 
 void ImageViewBase::SetHorizontalAlignment(Alignment alignment) {
diff --git a/ui/views/examples/table_example.cc b/ui/views/examples/table_example.cc
index c1aced2..c6225120 100644
--- a/ui/views/examples/table_example.cc
+++ b/ui/views/examples/table_example.cc
@@ -65,21 +65,20 @@
                                      MaximumFlexSizeRule::kUnbounded)
                        .WithWeight(1);
 
-  const auto make_checkbox = [](const std::u16string& label, int id,
-                                raw_ptr<TableView>* table,
-                                raw_ptr<Checkbox>* checkbox,
-                                FlexSpecification full_flex) {
-    return Builder<Checkbox>()
-        .CopyAddressTo(checkbox)
-        .SetText(label)
-        .SetCallback(base::BindRepeating(
-            [](int id, raw_ptr<TableView>* table, raw_ptr<Checkbox>* checkbox) {
-              (*table)->SetColumnVisibility(id, (*checkbox)->GetChecked());
-            },
-            id, table, checkbox))
-        .SetChecked(true)
-        .SetProperty(kFlexBehaviorKey, full_flex);
-  };
+  const auto make_checkbox =
+      [](const std::u16string& label, int id, raw_ptr<TableView>* table,
+         raw_ptr<Checkbox>* checkbox, FlexSpecification full_flex) {
+        return Builder<Checkbox>()
+            .CopyAddressTo(checkbox)
+            .SetText(label)
+            .SetCallback(base::BindRepeating(
+                [](int id, TableView* table, Checkbox* checkbox) {
+                  table->SetColumnVisibility(id, checkbox->GetChecked());
+                },
+                id, *table, *checkbox))
+            .SetChecked(true)
+            .SetProperty(kFlexBehaviorKey, full_flex);
+      };
 
   // Make table
   Builder<View>(container)
diff --git a/weblayer/browser/persistence/browser_persister.cc b/weblayer/browser/persistence/browser_persister.cc
index 5679b0a7..149d25b 100644
--- a/weblayer/browser/persistence/browser_persister.cc
+++ b/weblayer/browser/persistence/browser_persister.cc
@@ -6,11 +6,11 @@
 
 #include <stddef.h>
 
-#include <algorithm>
 #include <utility>
 #include <vector>
 
 #include "base/bind.h"
+#include "base/ranges/algorithm.h"
 #include "components/sessions/content/content_serialized_navigation_builder.h"
 #include "components/sessions/content/session_tab_helper.h"
 #include "components/sessions/core/command_storage_manager.h"
@@ -38,7 +38,7 @@
 
 int GetIndexOfTab(BrowserImpl* browser, Tab* tab) {
   const std::vector<Tab*>& tabs = browser->GetTabs();
-  auto iter = std::find(tabs.begin(), tabs.end(), tab);
+  auto iter = base::ranges::find(tabs, tab);
   DCHECK(iter != tabs.end());
   return static_cast<int>(iter - tabs.begin());
 }
diff --git a/weblayer/browser/persistence/minimal_browser_persister.cc b/weblayer/browser/persistence/minimal_browser_persister.cc
index 877de30b..08b52f9 100644
--- a/weblayer/browser/persistence/minimal_browser_persister.cc
+++ b/weblayer/browser/persistence/minimal_browser_persister.cc
@@ -6,6 +6,7 @@
 
 #include "base/containers/contains.h"
 #include "base/containers/cxx20_erase.h"
+#include "base/ranges/algorithm.h"
 #include "components/sessions/content/content_serialized_navigation_builder.h"
 #include "components/sessions/content/session_tab_helper.h"
 #include "components/sessions/core/session_command.h"
@@ -265,7 +266,7 @@
   auto tabs = browser->GetTabs();
   DCHECK(base::Contains(tabs, tab));
   const int tab_index =
-      static_cast<int>(std::find(tabs.begin(), tabs.end(), tab) - tabs.begin());
+      static_cast<int>(base::ranges::find(tabs, tab) - tabs.begin());
   if (!builder->AppendIfFits(BuildCommandsForTabConfiguration(
           browser_session_id, static_cast<TabImpl*>(tab), tab_index))) {
     return false;
@@ -324,9 +325,8 @@
   if (!browser->GetActiveTab())
     return -1;
   const std::vector<Tab*>& tabs = browser->GetTabs();
-  return static_cast<int>(
-      std::find(tabs.begin(), tabs.end(), browser->GetActiveTab()) -
-      tabs.begin());
+  return static_cast<int>(base::ranges::find(tabs, browser->GetActiveTab()) -
+                          tabs.begin());
 }
 
 }  // namespace
diff --git a/weblayer/browser/profile_disk_operations_unittests.cc b/weblayer/browser/profile_disk_operations_unittests.cc
index 377f40e..2011799 100644
--- a/weblayer/browser/profile_disk_operations_unittests.cc
+++ b/weblayer/browser/profile_disk_operations_unittests.cc
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <algorithm>
 #include <string>
 #include <vector>
 
 #include "base/base_paths.h"
 #include "base/check.h"
+#include "base/containers/contains.h"
 #include "base/files/file_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/test/scoped_path_override.h"
@@ -63,8 +63,7 @@
   std::vector<std::string> listed_names = ListProfileNames();
   EXPECT_EQ(names.size(), listed_names.size());
   for (const auto& name : names) {
-    auto itr = std::find(listed_names.begin(), listed_names.end(), name);
-    EXPECT_TRUE(itr != listed_names.end());
+    EXPECT_TRUE(base::Contains(listed_names, name));
   }
 }