diff --git a/DEPS b/DEPS
index ee8f8312..b36ceae 100644
--- a/DEPS
+++ b/DEPS
@@ -304,15 +304,15 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': 'f5b8452d9df682ecccc344736fb6c592162e2395',
+  'skia_revision': '7d27b3d0d2ab4055696fdecc9e462bd4c09c8277',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': 'a434e8ba99add65927db8d3c45506cb5cfdb7108',
+  'v8_revision': '7aa5c696c5975f8d00a1b9593a1ae6481616f0e9',
   # 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': 'e58e77f52b1ddf45a805058c70cc357a17db4b25',
+  'angle_revision': '598b4824eeb30c5d7ed57b2c69c7b67d84b96a23',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -383,7 +383,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': '2bed7ad2609f87d8275a009f77d8ef27c322d6a6',
+  'devtools_frontend_revision': '9975cad7f5b5956999154aaba4eb861ae5185063',
   # 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.
@@ -419,7 +419,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': '4411b2d57b5e9416540e02d249452c3dad889cc0',
+  'dawn_revision': 'dd54f74de15dbee21d4e6071b6e4060309123034',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -467,7 +467,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'libunwind_revision':    '5e22a7fe2335161ab267867c8e1be481bf6c8300',
+  'libunwind_revision':    'bb5988e15c56d4742574fc880c51ae104d5421b7',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -770,7 +770,7 @@
 
   'src/clank': {
     'url': 'https://chrome-internal.googlesource.com/clank/internal/apps.git' + '@' +
-    'e5d97aa4071de2bdc1fe82c584822f165af5c2fc',
+    'c005df50cd7ab6b9a52c95e538c039b8e5006eff',
     'condition': 'checkout_android and checkout_src_internal',
   },
 
@@ -869,7 +869,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/linux-amd64',
-          'version': 'neNaWSO9UyzMO-_r35CjYukqz80SZhFkczSKTDcyxwcC',
+          'version': 'ilV0jv_WJbZzkh0vuwzoP8l-y8LdRtyRvnQrtT7ByekC',
         },
       ],
       'dep_type': 'cipd',
@@ -880,7 +880,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/mac-amd64',
-          'version': 'iHUR_k1y2ex9kGEjGkp09d15xMa0MOV9r5fnnrdcK-0C',
+          'version': 'fmDR6rSXAs7oxOItk_YTx9CSCF53e0PqBLssITUT5X4C',
         },
       ],
       'dep_type': 'cipd',
@@ -891,7 +891,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/windows-amd64',
-          'version': '5i5GbwqElnNpTV29UDHu4MBy6_CQziVtIqBRRVqhk3cC',
+          'version': 'z8lTNWvTUXQ0rgbFW7xiIM6448jDeIl1dY9hsVfl-70C',
         },
       ],
       'dep_type': 'cipd',
@@ -1176,7 +1176,7 @@
   # Tools used when building Chrome for Chrome OS. This affects both the Simple
   # Chrome workflow, as well as the chromeos-chrome ebuild.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'ecaabf2d4d89186328e842b2870157d2833e7eb8',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '0fba8a897369b00d29e7c00bd789dc18e3f6552d',
       'condition': 'checkout_chromeos',
   },
 
@@ -1204,13 +1204,13 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'e38d195b635a0e73bf132d866fb659cec98492f5',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'a4eeafaa2fecd6196c63d67e7245f9fcf3b72870',
 
   'src/third_party/devtools-frontend/src':
     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' + '@' + 'e00ee13c2e6d4562109408d107ab1f5e89623e90',
+      'url': 'https://chrome-internal.googlesource.com/devtools/devtools-internal.git' + '@' + '9636f05e9c9a76c807ce6a5f3f91ffe15d492938',
     'condition': 'checkout_src_internal',
   },
 
@@ -1734,7 +1734,7 @@
     Var('chromium_git') + '/external/github.com/google/snappy.git' + '@' + '65dc7b383985eb4f63cd3e752136db8d9b4be8c0',
 
   'src/third_party/sqlite/src':
-    Var('chromium_git') + '/chromium/deps/sqlite.git' + '@' + 'a527890e56f1304053e5d9607aba139baf5b9245',
+    Var('chromium_git') + '/chromium/deps/sqlite.git' + '@' + '469aae8118e18b7354607f8ef09780cf8f3e54aa',
 
   'src/third_party/sqlite4java': {
       'packages': [
@@ -1899,7 +1899,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@1704eae453e8f757903885e17079452b4b645e56',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@7238ed39b1ff6346cea7304454ca289d1d0b9f5c',
     'condition': 'checkout_src_internal',
   },
 
@@ -1940,7 +1940,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/media_app/app',
-        'version': 'K3uMH0H46u8xmu7H5LAOhTafmXWF0_-k_ERw6AEWEUIC',
+        'version': '7RVywm_U56EmeD_vB7MS5c2IrWT8BS-MiOIFAkze-fsC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
index edd1e76..c3f1fe3 100644
--- a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
+++ b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
@@ -221,10 +221,6 @@
                     "Enables faster setTimeout(,0) by removing the 1 ms clamping."),
             Flag.baseFeature(BlinkFeatures.PAINT_HOLDING_CROSS_ORIGIN,
                     "Defers the first commit until FCP or timeout for cross-origin navigations."),
-            Flag.baseFeature(BlinkFeatures.HTML_PARAM_ELEMENT_URL_SUPPORT,
-                    "Enables the <param> element's URL-setting features (this functionality is"
-                            + " being deprecated and removed, so ENABLED is the safe/current"
-                            + " behavior, and DISABLED is the tested/new behavior)."),
             Flag.baseFeature(ContentFeatures.NAVIGATION_NETWORK_RESPONSE_QUEUE,
                     "Schedules tasks related to the navigation network responses on a higher "
                             + "priority task queue."),
@@ -360,6 +356,8 @@
             Flag.baseFeature(MetricsFeatures.METRICS_SERVICE_ASYNC_COLLECTION,
                     "Controls whether the metrics service creates periodic logs"
                             + " in a background thread or on the main thread."),
+            Flag.baseFeature(ContentFeatures.MAIN_THREAD_COMPOSITING_PRIORITY,
+                    "When enabled runs the main thread at compositing priority."),
             // Add new commandline switches and features above. The final entry should have a
             // trailing comma for cleaner diffs.
     };
diff --git a/ash/accelerators/accelerator_commands.cc b/ash/accelerators/accelerator_commands.cc
index 97d90d6..f5e8e2c 100644
--- a/ash/accelerators/accelerator_commands.cc
+++ b/ash/accelerators/accelerator_commands.cc
@@ -106,7 +106,7 @@
     "Accessibility.Shortcuts.CrosDockedMagnifier";
 const char kAccelWindowSnap[] = "Ash.Accelerators.WindowSnap";
 const char kAccelRotation[] = "Ash.Accelerators.Rotation.Usage";
-const char kAccelActivateDesk[] = "Ash.Accelerators.ActivateDesk";
+const char kAccelActivateDeskByIndex[] = "Ash.Accelerators.ActivateDeskByIndex";
 
 namespace accelerators {
 
@@ -153,7 +153,7 @@
 
 void RecordActivateDeskByIndexAcceleratorAction(
     const ActivateDeskAcceleratorAction& action) {
-  UMA_HISTOGRAM_ENUMERATION(kAccelActivateDesk, action);
+  UMA_HISTOGRAM_ENUMERATION(kAccelActivateDeskByIndex, action);
 }
 
 void RecordWindowSnapAcceleratorAction(
diff --git a/ash/ambient/ui/media_string_view.cc b/ash/ambient/ui/media_string_view.cc
index 9378ef0..d46e31d 100644
--- a/ash/ambient/ui/media_string_view.cc
+++ b/ash/ambient/ui/media_string_view.cc
@@ -245,7 +245,7 @@
     return;
   }
 
-  if (media_text_container_->layer()->gradient_mask().IsEmpty()) {
+  if (!media_text_container_->layer()->HasGradientMask()) {
     float fade_position = static_cast<float>(kMediaStringGradientWidthDip) /
                           media_text_container_->layer()->size().width();
     gfx::LinearGradient gradient_mask(/*angle=*/0);
diff --git a/ash/app_list/views/apps_container_view.cc b/ash/app_list/views/apps_container_view.cc
index 8646f66..7954e42 100644
--- a/ash/app_list/views/apps_container_view.cc
+++ b/ash/app_list/views/apps_container_view.cc
@@ -644,12 +644,12 @@
   if (!features::IsBackgroundBlurEnabled())
     return;
 
-  if (scrollable_container_->layer()->gradient_mask().IsEmpty())
+  if (!scrollable_container_->layer()->HasGradientMask())
     UpdateGradientMaskBounds();
 }
 
 void AppsContainerView::MaybeRemoveGradientMask() {
-  if (!scrollable_container_->layer()->gradient_mask().IsEmpty() &&
+  if (scrollable_container_->layer()->HasGradientMask() &&
       !keep_gradient_mask_for_cardified_state_) {
     scrollable_container_->layer()->SetGradientMask(
         gfx::LinearGradient::GetEmpty());
@@ -909,7 +909,7 @@
       gfx::Insets::TLBR(-kDefaultFadeoutMaskHeight, 0, 0, 0));
   scrollable_container_->SetBoundsRect(scrollable_bounds);
 
-  if (!scrollable_container_->layer()->gradient_mask().IsEmpty())
+  if (scrollable_container_->layer()->HasGradientMask())
     UpdateGradientMaskBounds();
 
   bool separator_need_centering = false;
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd
index e607e68..77805a1 100644
--- a/ash/ash_strings.grd
+++ b/ash/ash_strings.grd
@@ -3651,6 +3651,24 @@
       <message name="IDS_BROWSER_ACCELERATOR_DESCRIPTION_FOCUS_INACTIVE_POPUP_FOR_ACCESSIBILITY" translateable="false" desc="Label for accelerator action - Move focus to popups and dialogs.">
         Move focus to popups and dialogs
       </message>
+      <message name="IDS_BROWSER_ACCELERATOR_DESCRIPTION_BOTTOM_PAGE" translateable="false" desc="Label for accelerator action - Go to bottom of page.">
+        Go to bottom of page
+      </message>
+      <message name="IDS_BROWSER_ACCELERATOR_DESCRIPTION_TOP_PAGE" translateable="false" desc="Label for accelerator action - Go to top of page.">
+        Go to top of page
+      </message>
+      <message name="IDS_BROWSER_ACCELERATOR_DESCRIPTION_NEXT_PANE" translateable="false" desc="Label for accelerator action - Next pane.">
+        Next pane
+      </message>
+      <message name="IDS_BROWSER_ACCELERATOR_DESCRIPTION_PAGE_UP" translateable="false" desc="Label for accelerator action - Page up.">
+        Page up
+      </message>
+      <message name="IDS_BROWSER_ACCELERATOR_DESCRIPTION_PAGE_DOWN" translateable="false" desc="Label for accelerator action - Page down.">
+        Page down
+      </message>
+      <message name="IDS_BROWSER_ACCELERATOR_DESCRIPTION_RIGHT_CLICK" translateable="false" desc="Label for accelerator action - Right click a link.">
+        Right-click a link
+      </message>
       <message name="IDS_AMBIENT_ACCELERATOR_DESCRIPTION_GO_TO_TAB_IN_RANGE" translateable="false" desc="Label for accelerator action - Go to tabs 1 through 8.">
         Go to tabs 1 through 8
       </message>
@@ -3711,9 +3729,79 @@
       <message name="IDS_AMBIENT_ACCELERATOR_DESCRIPTION_ACTIVATE_INDEXED_DESK" translateable="false" desc="Label for accelerator description - Go to desk 1 to 8.">
         Go to desk 1 to 8
       </message>
+      <message name="IDS_AMBIENT_ACCELERATOR_DESCRIPTION_DISPLAY_HIDDEN_FILES" translateable="false" desc="Label for accelerator description - Display hidden files.">
+        Display hidden files in the Files app
+      </message>
+      <message name="IDS_AMBIENT_ACCELERATOR_DESCRIPTION_OPEN_RIGHT_CLICK_MENU" translateable="false" desc="Label for accelerator description - Open right-click menu for highlighted item.">
+        Open right-click menu for highlighted item
+      </message>
+      <message name="IDS_AMBIENT_ACCELERATOR_DESCRIPTION_CARET_BROWSING" translateable="false" desc="Label for accelerator description - Turn caret browsing on or off.">
+        Turn caret browsing on or off
+      </message>
+      <!-- Ambient Accelerator Action -->
       <message name="IDS_AMBIENT_ACCELERATOR_GO_TO_TAB_IN_RANGE" translateable="false" desc="Action for accelerator action - Go to tabs 1 through 8.">
         <ph name="MODIFIER">$1<ex>ctrl</ex></ph> <ph name="DELIMITER">$2<ex>+</ex></ph> <ph name="KEY_ONE">$3<ex>1</ex></ph> through <ph name="KEY_TWO">$4<ex>8</ex></ph>
       </message>
+      <message name="IDS_AMBIENT_ACCELERATOR_DRAG_LINK_IN_NEW_TAB" translateable="false" desc="Action for accelerator action - Open the link in a new tab.">
+        Drag link to blank area on the tab strip
+      </message>
+      <message name="IDS_AMBIENT_ACCELERATOR_OPEN_LINK_IN_TAB" translateable="false" desc="Action for accelerator action - Open the link in a new tab and switch to the new tab.">
+        Press <ph name="MODIFIER_1">$1<ex>ctrl</ex></ph> <ph name="MODIFIER_2">$2<ex>shift</ex></ph> and click a link
+      </message>
+      <message name="IDS_AMBIENT_ACCELERATOR_OPEN_LINK_IN_TAB_BACKGROUND" translateable="false" desc="Action for accelerator action - Open the link in a new tab in the background.">
+        Press <ph name="MODIFIER">$1<ex>ctrl</ex></ph> and click a link
+      </message>
+       <message name="IDS_AMBIENT_ACCELERATOR_OPEN_LINK_IN_WINDOW" translateable="false" desc="Action for accelerator action - Open the link in a new window.">
+        Press <ph name="MODIFIER">$1<ex>shift</ex></ph> and click a link
+      </message>
+      <message name="IDS_AMBIENT_ACCELERATOR_DRAG_LINK_IN_SAME_TAB" translateable="false" desc="Action for accelerator action - Open the link in the tab.">
+        Drag the link to the tab's address bar
+      </message>
+      <message name="IDS_AMBIENT_ACCELERATOR_OPEN_PAGE_IN_NEW_TAB" translateable="false" desc="Action for accelerator action - Open the webpage in a new tab.">
+        Type a web address in the address bar, then press <ph name="MODIFIER">$1<ex>alt</ex></ph><ph name="KEY">$2<ex>enter</ex></ph>
+      </message>
+      <message name="IDS_AMBIENT_ACCELERATOR_CYCLE_BACKWARD_MRU" translateable="false" desc="Action for accelerator action - Open the window that has been unused for the longest time.">
+        Press and hold <ph name="MODIFIER_1">$1<ex>alt</ex></ph><ph name="MODIFIER_2">$2<ex>shift</ex></ph>, tap <ph name="KEY">$3<ex>tab</ex></ph> until you get to the window you want to open, then release
+      </message>
+      <message name="IDS_AMBIENT_ACCELERATOR_FIND_NEXT" translateable="false" desc="Action for accelerator action - Go to the next match for your search.">
+        <ph name="MODIFIER">$1<ex>ctrl</ex></ph><ph name="KEY_ONE">$2<ex>g</ex></ph> or <ph name="KEY_TWO">$3<ex>enter</ex></ph>
+      </message>
+      <message name="IDS_AMBIENT_ACCELERATOR_FIND_PREVIOUS" translateable="false" desc="Action for accelerator action - Go to the previous match for your search.">
+        <ph name="MODIFIER_ONE">$1<ex>ctrl</ex></ph> <ph name="MODIFIER_TWO">$2<ex>shift</ex></ph> <ph name="KEY_ONE">$3<ex>g</ex></ph> or <ph name="MODIFIER_THREE">$4<ex>shift</ex></ph> <ph name="KEY_TWO">$5<ex>enter</ex></ph>
+      </message>
+      <message name="IDS_AMBIENT_ACCELERATOR_FOCUS_SEARCH" translateable="false" desc="Action for accelerator action - Place focus in search address bar.">
+        <ph name="MODIFIER">$1<ex>ctrl</ex></ph><ph name="KEY_ONE">$2<ex>k</ex></ph> or <ph name="KEY_TWO">$3<ex>e</ex></ph>
+      </message>
+      <message name="IDS_AMBIENT_ACCELERATOR_RELOAD" translateable="false" desc="Action for accelerator action - Reload your current page.">
+        <ph name="KEY_ONE">$1<ex>browser_refresh</ex></ph> or <ph name="MODIFIER">$2<ex>ctrl</ex></ph><ph name="KEY_TWO">$3<ex>r</ex></ph>
+      </message>
+      <message name="IDS_AMBIENT_ACCELERATOR_RIGHT_CLICK" translateable="false" desc="Action for accelerator action - Right-click a link.">
+        Press <ph name="MODIFIER">$1<ex>alt</ex></ph> and click a link
+      </message>
+      <message name="IDS_AMBIENT_ACCELERATOR_SAVE_LINK_AS_BOOKMARK" translateable="false" desc="Action for accelerator action - Drag link to bookmarks bar.">
+        Drag link to bookmarks bar
+      </message>
+      <message name="IDS_AMBIENT_ACCELERATOR_SHOW_APP_MENU" translateable="false" desc="Action for accelerator action - Show app menu.">
+        <ph name="MODIFIER">$1<ex>alt</ex></ph><ph name="KEY_ONE">$2<ex>e</ex></ph> or <ph name="KEY_TWO">$3<ex>f</ex></ph>
+      </message>
+      <message name="IDS_AMBIENT_ACCELERATOR_LAUNCH_NUMBERED_APP" translateable="false" desc="Action for accelerator action - Click icons 1-8 on your shelf.">
+        <ph name="MODIFIER">$1<ex>alt</ex></ph> <ph name="DELIMITER">$2<ex>+</ex></ph> <ph name="KEY_ONE">$3<ex>1</ex></ph> through <ph name="KEY_TWO">$4<ex>8</ex></ph>
+      </message>
+      <message name="IDS_AMBIENT_ACCELERATOR_OPEN_FILE" translateable="false" desc="Action for accelerator action - Preview a file in the Files app.">
+        Select the file, then press <ph name="KEY">$1<ex>space</ex></ph>
+      </message>
+      <message name="IDS_AMBIENT_ACCELERATOR_HIGHLIGHT_NEXT_ITEM_ON_SHELF" translateable="false" desc="Action for accelerator action - Highlight the next item on your shelf.">
+        <ph name="MODIFIER_ONE">$1<ex>shift</ex></ph> <ph name="MODIFIER_TWO">$2<ex>alt</ex></ph> <ph name="KEY_ONE">$3<ex>i</ex></ph> then <ph name="KEY_TWO">$4<ex>tab</ex></ph> or <ph name="KEY_THREE">$5<ex>right</ex></ph>
+      </message>
+      <message name="IDS_AMBIENT_ACCELERATOR_HIGHTLIGHT_PREVIOUS_ITEM_ON_SHELF" translateable="false" desc="Action for accelerator action - Highlight the previous item on your shelf.">
+        <ph name="MODIFIER_ONE">$1<ex>shift</ex></ph> <ph name="MODIFIER_TWO">$2<ex>alt</ex></ph> <ph name="KEY_ONE">$3<ex>i</ex></ph> then <ph name="KEY_TWO">$4<ex>tab</ex></ph> <ph name="MODIFIER_THREE">$5<ex>shift</ex></ph> or <ph name="KEY_THREE">$6<ex>left</ex></ph>
+      </message>
+      <message name="IDS_AMBIENT_ACCELERATOR_OPEN_HIGHLIGHTED_ITEM_ON_SHELF" translateable="false" desc="Action for accelerator action - Open the highlighted item on your shelf.">
+        <ph name="MODIFIER_ONE">$1<ex>shift</ex></ph> <ph name="MODIFIER_TWO">$2<ex>alt</ex></ph> <ph name="KEY_ONE">$3<ex>i</ex></ph> then <ph name="KEY_TWO">$4<ex>space</ex></ph> or <ph name="KEY_THREE">$5<ex>enter</ex></ph>
+      </message>
+      <message name="IDS_AMBIENT_ACCELERATOR_REMOVE_HIGHLIGHT_ON_SHELF" translateable="false" desc="Action for accelerator action - Remove the highlight from an item on your shelf.">
+        <ph name="MODIFIER_ONE">$1<ex>shift</ex></ph> <ph name="MODIFIER_TWO">$2<ex>alt</ex></ph> <ph name="KEY_ONE">$3<ex>i</ex></ph> then <ph name="KEY_TWO">$4<ex>esc</ex></ph>
+      </message>
 
       <!-- Tray scale strings -->
       <message name="IDS_ASH_STATUS_TRAY_SCALE" desc="The label used in scale setting detailed page of ash tray popup.">
diff --git a/ash/controls/scroll_view_gradient_helper.cc b/ash/controls/scroll_view_gradient_helper.cc
index ad8d132..c8ee697 100644
--- a/ash/controls/scroll_view_gradient_helper.cc
+++ b/ash/controls/scroll_view_gradient_helper.cc
@@ -111,7 +111,7 @@
 }
 
 void ScrollViewGradientHelper::RemoveMaskLayer() {
-  if (scroll_view_->layer()->gradient_mask().IsEmpty())
+  if (!scroll_view_->layer()->HasGradientMask())
     return;
 
   DVLOG(1) << "Removing gradient mask";
diff --git a/ash/public/cpp/metrics_util.cc b/ash/public/cpp/metrics_util.cc
index 8084bdc1..7f752d3 100644
--- a/ash/public/cpp/metrics_util.cc
+++ b/ash/public/cpp/metrics_util.cc
@@ -7,6 +7,7 @@
 #include "base/check.h"
 #include "base/functional/bind.h"
 #include "base/no_destructor.h"
+#include "base/time/time.h"
 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
 
 namespace ash {
@@ -16,20 +17,25 @@
 
 bool g_data_collection_enabled = false;
 
-std::vector<cc::FrameSequenceMetrics::CustomReportData>& GetDataCollector() {
-  static base::NoDestructor<
-      std::vector<cc::FrameSequenceMetrics::CustomReportData>>
-      data;
+std::vector<AnimationData>& GetDataCollector() {
+  static base::NoDestructor<std::vector<AnimationData>> data;
   return *data;
 }
 
 void CollectDataAndForwardReport(
+    base::TimeTicks start_tick,
     ReportCallback callback,
     const cc::FrameSequenceMetrics::CustomReportData& data) {
   // An arbitrary cap on the maximum number of animations being collected.
   DCHECK_LT(GetDataCollector().size(), 1000u);
 
-  GetDataCollector().push_back(data);
+  AnimationData animation_data = {
+      .start_tick = start_tick,
+      .stop_tick = base::TimeTicks::Now(),
+      .smoothness_data = data,
+  };
+
+  GetDataCollector().emplace_back(std::move(animation_data));
   std::move(callback).Run(data);
 }
 
@@ -64,6 +70,7 @@
     return forward_smoothness;
 
   return base::BindRepeating(&CollectDataAndForwardReport,
+                             base::TimeTicks::Now(),
                              std::move(forward_smoothness));
 }
 
@@ -72,15 +79,15 @@
   g_data_collection_enabled = true;
 }
 
-std::vector<cc::FrameSequenceMetrics::CustomReportData> StopDataCollection() {
+std::vector<AnimationData> StopDataCollection() {
   DCHECK(g_data_collection_enabled);
   g_data_collection_enabled = false;
 
   return GetCollectedData();
 }
 
-std::vector<cc::FrameSequenceMetrics::CustomReportData> GetCollectedData() {
-  std::vector<cc::FrameSequenceMetrics::CustomReportData> data;
+std::vector<AnimationData> GetCollectedData() {
+  std::vector<AnimationData> data;
   data.swap(GetDataCollector());
   return data;
 }
diff --git a/ash/public/cpp/metrics_util.h b/ash/public/cpp/metrics_util.h
index 54e00ecf..98d894f9 100644
--- a/ash/public/cpp/metrics_util.h
+++ b/ash/public/cpp/metrics_util.h
@@ -9,6 +9,7 @@
 
 #include "ash/public/cpp/ash_public_export.h"
 #include "base/functional/callback.h"
+#include "base/time/time.h"
 #include "cc/metrics/frame_sequence_metrics.h"
 
 namespace ash {
@@ -18,6 +19,18 @@
     const cc::FrameSequenceMetrics::CustomReportData&)>;
 using SmoothnessCallback = base::RepeatingCallback<void(int smoothness)>;
 
+// Animation smoothness data collected between `StartDataCollection` and
+// `StopDataCollection`, and reported from `GetCollectedData`.
+struct ASH_PUBLIC_EXPORT AnimationData {
+  // When an animation starts. It is recorded when `ForSmoothness` is
+  // called, which happens when the animation is created.
+  base::TimeTicks start_tick;
+  // When an animation stops. It is recorded when smoothness data is reported.
+  base::TimeTicks stop_tick;
+  // Collected smoothness data.
+  cc::FrameSequenceMetrics::CustomReportData smoothness_data;
+};
+
 // Returns a ReportCallback that could be passed to ui::ThroughputTracker
 // or ui::AnimationThroughputReporter. The returned callback picks up the
 // cc::FrameSequenceMetrics::ThroughputData, calculates the smoothness
@@ -31,12 +44,10 @@
 ASH_PUBLIC_EXPORT void StartDataCollection();
 
 // Stops data collection and returns the data collected since starting.
-ASH_PUBLIC_EXPORT std::vector<cc::FrameSequenceMetrics::CustomReportData>
-StopDataCollection();
+ASH_PUBLIC_EXPORT std::vector<AnimationData> StopDataCollection();
 
 // Gets the currently collected data and clears it after return.
-ASH_PUBLIC_EXPORT std::vector<cc::FrameSequenceMetrics::CustomReportData>
-GetCollectedData();
+ASH_PUBLIC_EXPORT std::vector<AnimationData> GetCollectedData();
 
 // Returns smoothness calculated from given data.
 ASH_PUBLIC_EXPORT int CalculateSmoothness(
diff --git a/ash/public/mojom/accelerator_info.mojom b/ash/public/mojom/accelerator_info.mojom
index 2faa9fd..6bba511 100644
--- a/ash/public/mojom/accelerator_info.mojom
+++ b/ash/public/mojom/accelerator_info.mojom
@@ -105,7 +105,7 @@
 // An accelerator that can display arbitrary text with optional modifiers/keys
 // interspersed.
 struct TextAcceleratorProperties {
-  array<TextAcceleratorPart> text_accelerator;
+  array<TextAcceleratorPart> parts;
 };
 
 // An accelerator that has at least one modifier and a set of keys.
diff --git a/ash/shelf/scrollable_shelf_view.cc b/ash/shelf/scrollable_shelf_view.cc
index 4ebab78e6..a971f3114 100644
--- a/ash/shelf/scrollable_shelf_view.cc
+++ b/ash/shelf/scrollable_shelf_view.cc
@@ -2120,7 +2120,7 @@
   const bool strategy_needs_update = (layout_strategy_ != new_strategy);
   if (strategy_needs_update) {
     layout_strategy_ = new_strategy;
-    const bool has_gradient_zone = !layer()->gradient_mask().IsEmpty();
+    const bool has_gradient_zone = layer()->HasGradientMask();
     const bool should_have_gradient_zone = ShouldApplyMaskLayerGradientZone();
     if (has_gradient_zone && !should_have_gradient_zone) {
       layer()->SetGradientMask(gfx::LinearGradient::GetEmpty());
diff --git a/ash/style/color_palette_controller.cc b/ash/style/color_palette_controller.cc
index 52fa7c3..024643a 100644
--- a/ash/style/color_palette_controller.cc
+++ b/ash/style/color_palette_controller.cc
@@ -74,18 +74,15 @@
     return absl::nullopt;
   }
 
-  void GenerateSampleScheme(ColorScheme scheme,
-                            SampleSchemeCallback callback) const override {
-    // TODO(b/258719005): Return correct and different schemes for each
-    // `scheme`.
-    DCHECK_NE(scheme, ColorScheme::kStatic)
-        << "Requesting a static scheme doesn't make sense since there is no "
-           "seed color";
-    SampleScheme sample = {.primary = SK_ColorRED,
-                           .secondary = SK_ColorGREEN,
-                           .tertiary = SK_ColorBLUE};
+  void GenerateSampleColorSchemes(
+      const std::vector<ColorScheme>& color_scheme_buttons,
+      SampleColorSchemeCallback callback) const override {
+    std::vector<SampleColorScheme> samples;
+    for (auto scheme : color_scheme_buttons) {
+      samples.push_back(GenerateSampleColorScheme(scheme));
+    }
     base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
-        FROM_HERE, base::BindOnce(std::move(callback), sample),
+        FROM_HERE, base::BindOnce(std::move(callback), samples),
         base::Milliseconds(20));
   }
 
@@ -93,6 +90,18 @@
   SkColor static_color_ = SK_ColorBLUE;
   ColorScheme current_scheme_ = ColorScheme::kTonalSpot;
   base::ObserverList<ColorPaletteController::Observer> observers_;
+
+  SampleColorScheme GenerateSampleColorScheme(ColorScheme scheme) const {
+    // TODO(b/258719005): Return correct and different schemes for each
+    // `scheme`.
+    DCHECK_NE(scheme, ColorScheme::kStatic)
+        << "Requesting a static scheme doesn't make sense since there is no "
+           "seed color";
+    return {.scheme = scheme,
+            .primary = SK_ColorRED,
+            .secondary = SK_ColorGREEN,
+            .tertiary = SK_ColorBLUE};
+  }
 };
 
 }  // namespace
diff --git a/ash/style/color_palette_controller.h b/ash/style/color_palette_controller.h
index 544cec1d..790cc08 100644
--- a/ash/style/color_palette_controller.h
+++ b/ash/style/color_palette_controller.h
@@ -34,6 +34,20 @@
   ui::ColorProviderManager::ColorMode color_mode;
 };
 
+// Samples of color schemes for the tri-color scheme previews.
+struct ASH_EXPORT SampleColorScheme {
+  ColorScheme scheme;
+  SkColor primary;
+  SkColor secondary;
+  SkColor tertiary;
+
+  bool operator==(const SampleColorScheme& other) const {
+    return std::tie(primary, secondary, tertiary, scheme) ==
+           std::tie(other.primary, other.secondary, other.tertiary,
+                    other.scheme);
+  }
+};
+
 // Manages data for the current color scheme which is used to generate a color
 // palette. Colors are derived from the seed color, scheme type, and dark/light
 // mode state. This class is intended for other controllers. Views should
@@ -42,13 +56,6 @@
 // of this class.
 class ASH_EXPORT ColorPaletteController {
  public:
-  // Samples of color schemes for the tri-color scheme previews.
-  struct SampleScheme {
-    SkColor primary;
-    SkColor secondary;
-    SkColor tertiary;
-  };
-
   class Observer : public base::CheckedObserver {
    public:
     // Called when the color palette is about to change but before the
@@ -94,13 +101,15 @@
   // Iff a static color is the currently selected scheme, returns that color.
   virtual absl::optional<SkColor> static_color() const = 0;
 
-  // Generates a tri-color SampleScheme based on the current configuration for
-  // the provided `scheme`. i.e. uses the current seed_color and color_mode with
-  // the chosen `scheme`. The generated scheme is provided through
+  // Generates a tri-color SampleColorScheme based on the current configuration
+  // for the provided `scheme`. i.e. uses the current seed_color and color_mode
+  // with the chosen `scheme`. The generated scheme is provided through
   // `callback`.
-  using SampleSchemeCallback = base::OnceCallback<void(SampleScheme)>;
-  virtual void GenerateSampleScheme(ColorScheme scheme,
-                                    SampleSchemeCallback callback) const = 0;
+  using SampleColorSchemeCallback =
+      base::OnceCallback<void(const std::vector<ash::SampleColorScheme>&)>;
+  virtual void GenerateSampleColorSchemes(
+      const std::vector<ColorScheme>& color_scheme_buttons,
+      SampleColorSchemeCallback callback) const = 0;
 };
 
 }  // namespace ash
diff --git a/ash/system/bluetooth/bluetooth_feature_pod_controller.cc b/ash/system/bluetooth/bluetooth_feature_pod_controller.cc
index 6e0979a..2f402eb 100644
--- a/ash/system/bluetooth/bluetooth_feature_pod_controller.cc
+++ b/ash/system/bluetooth/bluetooth_feature_pod_controller.cc
@@ -25,6 +25,7 @@
 #include "ui/base/l10n/l10n_util.h"
 
 namespace ash {
+namespace {
 
 using bluetooth_config::GetPairedDeviceName;
 using bluetooth_config::mojom::BluetoothModificationState;
@@ -32,9 +33,22 @@
 using bluetooth_config::mojom::BluetoothSystemState;
 using bluetooth_config::mojom::DeviceConnectionState;
 
+BluetoothSystemState GetInitialSystemState() {
+  if (features::IsQsRevampEnabled()) {
+    // Ensure the feature tile is visible while waiting for the async mojo query
+    // in the constructor. This simplifies the initial QS layout.
+    return BluetoothSystemState::kEnabled;
+  } else {
+    return BluetoothSystemState::kUnavailable;
+  }
+}
+
+}  // namespace
+
 BluetoothFeaturePodController::BluetoothFeaturePodController(
     UnifiedSystemTrayController* tray_controller)
-    : tray_controller_(tray_controller) {
+    : system_state_(GetInitialSystemState()),
+      tray_controller_(tray_controller) {
   GetBluetoothConfigService(
       remote_cros_bluetooth_config_.BindNewPipeAndPassReceiver());
   remote_cros_bluetooth_config_->ObserveSystemProperties(
diff --git a/ash/system/bluetooth/bluetooth_feature_pod_controller.h b/ash/system/bluetooth/bluetooth_feature_pod_controller.h
index d202e9e..32ad29c 100644
--- a/ash/system/bluetooth/bluetooth_feature_pod_controller.h
+++ b/ash/system/bluetooth/bluetooth_feature_pod_controller.h
@@ -90,8 +90,7 @@
   bluetooth_config::mojom::BluetoothModificationState modification_state_ =
       bluetooth_config::mojom::BluetoothModificationState::
           kCannotModifyBluetooth;
-  bluetooth_config::mojom::BluetoothSystemState system_state_ =
-      bluetooth_config::mojom::BluetoothSystemState::kUnavailable;
+  bluetooth_config::mojom::BluetoothSystemState system_state_;
   FeaturePodButton* button_ = nullptr;  // Owned by views hierarchy.
   FeatureTile* tile_ = nullptr;         // Owned by views hierarchy.
   UnifiedSystemTrayController* tray_controller_;
diff --git a/ash/system/bluetooth/bluetooth_feature_pod_controller_unittest.cc b/ash/system/bluetooth/bluetooth_feature_pod_controller_unittest.cc
index 9517d0df..d9d6586 100644
--- a/ash/system/bluetooth/bluetooth_feature_pod_controller_unittest.cc
+++ b/ash/system/bluetooth/bluetooth_feature_pod_controller_unittest.cc
@@ -592,4 +592,19 @@
                                       /*expected_count=*/1);
 }
 
+TEST_P(BluetoothFeaturePodControllerTest, VisibilityOnConstruction) {
+  BluetoothFeaturePodController controller(tray_controller());
+  if (IsQsRevampEnabled()) {
+    // Create a feature tile but don't spin the message loop.
+    auto tile = controller.CreateTile();
+    // System state defaults to "enabled" so the tile is visible.
+    EXPECT_TRUE(tile->GetVisible());
+  } else {
+    // Create a feature pod button but don't spin the message loop.
+    auto button = base::WrapUnique(controller.CreateButton());
+    // System state defaults to "unavailable" so the button is invisible.
+    EXPECT_FALSE(button->GetVisible());
+  }
+}
+
 }  // namespace ash
diff --git a/ash/system/progress_indicator/progress_indicator_animation_registry.cc b/ash/system/progress_indicator/progress_indicator_animation_registry.cc
index 5862dad..c70bc1cb 100644
--- a/ash/system/progress_indicator/progress_indicator_animation_registry.cc
+++ b/ash/system/progress_indicator/progress_indicator_animation_registry.cc
@@ -59,15 +59,19 @@
     it->second.set_removal_callback(base::BindRepeating(
         [](KeyedAnimationChangedCallbackListMap<CallbackListType>*
                animation_changed_callback_lists_by_key,
-           const void* key) {
+           MayBeDangling<const void> key) {
           auto it = animation_changed_callback_lists_by_key->find(key);
           if (it != animation_changed_callback_lists_by_key->end() &&
               it->second.empty()) {
             animation_changed_callback_lists_by_key->erase(it);
           }
         },
+        // base::Unretained is safe, because this object is owning the callback.
         base::Unretained(animation_changed_callback_lists_by_key),
-        base::Unretained(key)));
+        // TODO(b/265440023) `key` may be a pointer to freed memory. Consider
+        // using base::IdType instead of void* to key the
+        // ProgressIndicatorAnimationRegistry.
+        base::UnsafeDangling(key)));
   }
 
   return it->second.Add(std::move(callback));
diff --git a/ash/webui/personalization_app/mojom/BUILD.gn b/ash/webui/personalization_app/mojom/BUILD.gn
index 31de432..5649ab4 100644
--- a/ash/webui/personalization_app/mojom/BUILD.gn
+++ b/ash/webui/personalization_app/mojom/BUILD.gn
@@ -76,6 +76,10 @@
           mojom = "ash.personalization_app.mojom.ColorScheme"
           cpp = "ash::ColorScheme"
         },
+        {
+          mojom = "ash.personalization_app.mojom.SampleColorScheme"
+          cpp = "ash::SampleColorScheme"
+        },
       ]
       traits_headers = [ "personalization_app_mojom_traits.h" ]
       traits_sources = [ "personalization_app_mojom_traits.cc" ]
diff --git a/ash/webui/personalization_app/mojom/personalization_app.mojom b/ash/webui/personalization_app/mojom/personalization_app.mojom
index 55ed1582..2c8d6f1f 100644
--- a/ash/webui/personalization_app/mojom/personalization_app.mojom
+++ b/ash/webui/personalization_app/mojom/personalization_app.mojom
@@ -324,6 +324,7 @@
     CancelPreviewWallpaper();
 };
 
+// Color scheme options used to generate the system UI's color palette.
 enum ColorScheme {
   kStatic = 0,
   kTonalSpot = 1,
@@ -332,6 +333,14 @@
   kVibrant = 4,
 };
 
+// Samples of a color scheme for the tri-color scheme preview.
+struct SampleColorScheme {
+  ColorScheme scheme;
+  skia.mojom.SkColor primary;
+  skia.mojom.SkColor secondary;
+  skia.mojom.SkColor tertiary;
+};
+
 // Receives information whenever there are theme related changes such as color
 // mode.
 interface ThemeObserver {
@@ -374,6 +383,9 @@
   // Retrieves the static seed color for dynamic color.
   GetStaticColor() => (skia.mojom.SkColor? static_color);
 
+  // Generate samples of all the color schemes.
+  GenerateSampleColorSchemes() => (array<SampleColorScheme> sample_color_schemes);
+
   // Returns whether color mode auto scheduler is enabled.
   IsColorModeAutoScheduleEnabled() => (bool enabled);
 
diff --git a/ash/webui/personalization_app/mojom/personalization_app_mojom_traits.cc b/ash/webui/personalization_app/mojom/personalization_app_mojom_traits.cc
index 3e517d4..4b4d6dd 100644
--- a/ash/webui/personalization_app/mojom/personalization_app_mojom_traits.cc
+++ b/ash/webui/personalization_app/mojom/personalization_app_mojom_traits.cc
@@ -198,7 +198,7 @@
 }
 
 // Default to false as we don't ever need to convert back to
-// |backdrop::Collection|
+// `backdrop::Collection`
 bool StructTraits<ash::personalization_app::mojom::WallpaperCollectionDataView,
                   backdrop::Collection>::
     Read(ash::personalization_app::mojom::WallpaperCollectionDataView data,
@@ -245,7 +245,7 @@
 }
 
 // Default to false as we don't ever need to convert back to
-// |backdrop::Image|
+// `Backdrop::Image`
 bool StructTraits<ash::personalization_app::mojom::WallpaperImageDataView,
                   backdrop::Image>::
     Read(ash::personalization_app::mojom::WallpaperImageDataView data,
@@ -505,4 +505,40 @@
   return false;
 }
 
+SkColor
+StructTraits<ash::personalization_app::mojom::SampleColorSchemeDataView,
+             ash::SampleColorScheme>::primary(const ash::SampleColorScheme&
+                                                  sample_color_scheme) {
+  return sample_color_scheme.primary;
+}
+
+SkColor
+StructTraits<ash::personalization_app::mojom::SampleColorSchemeDataView,
+             ash::SampleColorScheme>::secondary(const ash::SampleColorScheme&
+                                                    sample_color_scheme) {
+  return sample_color_scheme.secondary;
+}
+
+SkColor
+StructTraits<ash::personalization_app::mojom::SampleColorSchemeDataView,
+             ash::SampleColorScheme>::tertiary(const ash::SampleColorScheme&
+                                                   sample_color_scheme) {
+  return sample_color_scheme.tertiary;
+}
+
+ash::ColorScheme
+StructTraits<ash::personalization_app::mojom::SampleColorSchemeDataView,
+             ash::SampleColorScheme>::scheme(const ash::SampleColorScheme&
+                                                 sample_color_scheme) {
+  return sample_color_scheme.scheme;
+}
+
+// Default to false as we don't ever need to convert back to
+// `ash::ColorSchemeSample`.
+bool StructTraits<ash::personalization_app::mojom::SampleColorSchemeDataView,
+                  ash::SampleColorScheme>::
+    Read(ash::personalization_app::mojom::SampleColorSchemeDataView data,
+         ash::SampleColorScheme* out) {
+  return false;
+}
 }  // namespace mojo
diff --git a/ash/webui/personalization_app/mojom/personalization_app_mojom_traits.h b/ash/webui/personalization_app/mojom/personalization_app_mojom_traits.h
index e8daa39..1118774c 100644
--- a/ash/webui/personalization_app/mojom/personalization_app_mojom_traits.h
+++ b/ash/webui/personalization_app/mojom/personalization_app_mojom_traits.h
@@ -170,6 +170,19 @@
   static bool FromMojom(MojomColorScheme input, ash::ColorScheme* output);
 };
 
+template <>
+struct StructTraits<ash::personalization_app::mojom::SampleColorSchemeDataView,
+                    ash::SampleColorScheme> {
+  static ash::ColorScheme scheme(
+      const ash::SampleColorScheme& sample_color_scheme);
+  static SkColor primary(const ash::SampleColorScheme& sample_color_scheme);
+  static SkColor secondary(const ash::SampleColorScheme& sample_color_scheme);
+  static SkColor tertiary(const ash::SampleColorScheme& sample_color_scheme);
+  static bool Read(
+      ash::personalization_app::mojom::SampleColorSchemeDataView data,
+      ash::SampleColorScheme* out);
+};
+
 }  // namespace mojo
 
 #endif  // ASH_WEBUI_PERSONALIZATION_APP_MOJOM_PERSONALIZATION_APP_MOJOM_TRAITS_H_
diff --git a/ash/webui/personalization_app/resources/js/personalization_app.ts b/ash/webui/personalization_app/resources/js/personalization_app.ts
index 5e0495d..6693827 100644
--- a/ash/webui/personalization_app/resources/js/personalization_app.ts
+++ b/ash/webui/personalization_app/resources/js/personalization_app.ts
@@ -78,7 +78,7 @@
 export {PersonalizationStore} from './personalization_store.js';
 export {PersonalizationThemeElement} from './theme/personalization_theme_element.js';
 export {PersonalizationToastElement} from './personalization_toast_element.js';
-export {setDarkModeEnabledAction, SetDarkModeEnabledAction, setColorSchemeAction, setStaticColorAction, SetStaticColorPrefAction, SetColorSchemePrefAction, ThemeActionName, ThemeActions} from './theme/theme_actions.js';
+export {setDarkModeEnabledAction, SetDarkModeEnabledAction, setColorSchemeAction, setStaticColorAction, SetStaticColorAction, SetSampleColorSchemesAction, SetColorSchemeAction, ThemeActionName, ThemeActions} from './theme/theme_actions.js';
 export {setThemeProviderForTesting} from './theme/theme_interface_provider.js';
 export {ColorSchemeIconSvgElement} from './theme/color_scheme_icon_svg_element.js';
 export {DynamicColorElement} from './theme/dynamic_color_element.js';
diff --git a/ash/webui/personalization_app/resources/js/theme/color_scheme_icon_svg_element.html b/ash/webui/personalization_app/resources/js/theme/color_scheme_icon_svg_element.html
index 6abee19..4d811e1 100644
--- a/ash/webui/personalization_app/resources/js/theme/color_scheme_icon_svg_element.html
+++ b/ash/webui/personalization_app/resources/js/theme/color_scheme_icon_svg_element.html
@@ -1,5 +1,5 @@
 <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48" fill="none">
-    <path fill$="[[scheme.primaryColor]]" d="M0.000120163 24C0.000120742 10.7452 10.7453 -2.48674e-06 24.0001 -1.90735e-06C37.255 -1.32796e-06 48.0001 10.7452 48.0001 24L0.000120163 24Z"/>
-    <path fill$="[[scheme.secondaryColor]]" d="M24 48C37.2548 48 48.0001 37.2548 48.0001 24L24 24L24 48Z"/>
-    <path fill$="[[scheme.tertiaryColor]]" d="M0.000120163 24C0.000118997 37.3335 10.7451 48 24 48L24 24L0.000120163 24Z"/>
-</svg>
\ No newline at end of file
+    <path fill$="[[getHexColor_(scheme.primary)]]" d="M0.000120163 24C0.000120742 10.7452 10.7453 -2.48674e-06 24.0001 -1.90735e-06C37.255 -1.32796e-06 48.0001 10.7452 48.0001 24L0.000120163 24Z"></path>
+    <path fill$="[[getHexColor_(scheme.secondary)]]" d="M24 48C37.2548 48 48.0001 37.2548 48.0001 24L24 24L24 48Z"></path>
+    <path fill$="[[getHexColor_(scheme.tertiary)]]" d="M0.000120163 24C0.000118997 37.3335 10.7451 48 24 48L24 24L0.000120163 24Z"></path>
+</svg>
diff --git a/ash/webui/personalization_app/resources/js/theme/color_scheme_icon_svg_element.ts b/ash/webui/personalization_app/resources/js/theme/color_scheme_icon_svg_element.ts
index ba6ddd18..dbe2cf4 100644
--- a/ash/webui/personalization_app/resources/js/theme/color_scheme_icon_svg_element.ts
+++ b/ash/webui/personalization_app/resources/js/theme/color_scheme_icon_svg_element.ts
@@ -6,10 +6,13 @@
  * @fileoverview This component is for the color scheme icon svg.
  */
 
+import {SkColor} from 'chrome://resources/mojo/skia/public/mojom/skcolor.mojom-webui.js';
+
+import {SampleColorScheme} from '../personalization_app.mojom-webui.js';
 import {WithPersonalizationStore} from '../personalization_store.js';
+import {convertToRgbHexStr} from '../utils.js';
 
 import {getTemplate} from './color_scheme_icon_svg_element.html.js';
-import {DynamicColorScheme} from './dynamic_color_element.js';
 
 export class ColorSchemeIconSvgElement extends WithPersonalizationStore {
   static get is() {
@@ -28,7 +31,14 @@
       },
     };
   }
-  private scheme_: DynamicColorScheme;
+  private scheme_: SampleColorScheme;
+
+  private getHexColor_(color: SkColor): string {
+    if (!color || !color.value) {
+      return 'none';
+    }
+    return convertToRgbHexStr(color.value);
+  }
 }
 
 customElements.define(ColorSchemeIconSvgElement.is, ColorSchemeIconSvgElement);
diff --git a/ash/webui/personalization_app/resources/js/theme/dynamic_color_element.html b/ash/webui/personalization_app/resources/js/theme/dynamic_color_element.html
index 32d0632..2ff1c847 100644
--- a/ash/webui/personalization_app/resources/js/theme/dynamic_color_element.html
+++ b/ash/webui/personalization_app/resources/js/theme/dynamic_color_element.html
@@ -75,13 +75,13 @@
       id="colorSchemeSelector"
       selected="0"
       selected-item="{{colorSchemeHighlightedButton_}}"
-      hidden$="[[!automaticSeedColorEnabled]]">
-    <template is="dom-repeat" items="[[colorSchemes_]]" as="colorScheme">
+      hidden="[[!automaticSeedColorEnabled]]">
+    <template is="dom-repeat" items="[[sampleColorSchemes_]]" as="colorScheme">
       <cr-button
-          tabindex$="[[getTabIndex_(colorScheme.id)]]"
+          tabindex$="[[getTabIndex_(colorScheme.scheme)]]"
           on-click="onClickColorSchemeButton_"
-          data-color-scheme-id$="[[colorScheme.id]]"
-          aria-checked$="[[getColorSchemeAriaChecked_(colorScheme.id, colorSchemeSelected_)]]">
+          data-color-scheme-id$="[[colorScheme.scheme]]"
+          aria-checked$="[[getColorSchemeAriaChecked_(colorScheme.scheme, colorSchemeSelected_)]]">
         <color-scheme-icon-svg scheme="[[colorScheme]]"></color-scheme-icon-svg>
       </cr-button>
     </template>
diff --git a/ash/webui/personalization_app/resources/js/theme/dynamic_color_element.ts b/ash/webui/personalization_app/resources/js/theme/dynamic_color_element.ts
index 7ce3b55..2506c885 100644
--- a/ash/webui/personalization_app/resources/js/theme/dynamic_color_element.ts
+++ b/ash/webui/personalization_app/resources/js/theme/dynamic_color_element.ts
@@ -18,7 +18,7 @@
 import {IronA11yKeysElement} from 'chrome://resources/polymer/v3_0/iron-a11y-keys/iron-a11y-keys.js';
 import {IronSelectorElement} from 'chrome://resources/polymer/v3_0/iron-selector/iron-selector.js';
 
-import {ColorScheme} from '../personalization_app.mojom-webui.js';
+import {ColorScheme, SampleColorScheme} from '../personalization_app.mojom-webui.js';
 import {WithPersonalizationStore} from '../personalization_store.js';
 import {convertToRgbHexStr} from '../utils.js';
 
@@ -27,13 +27,6 @@
 import {getThemeProvider} from './theme_interface_provider.js';
 import {ThemeObserver} from './theme_observer.js';
 
-export interface DynamicColorScheme {
-  id: ColorScheme;
-  primaryColor: string;
-  secondaryColor: string;
-  tertiaryColor: string;
-}
-
 export interface DynamicColorElement {
   $: {
     staticColorKeys: IronA11yKeysElement,
@@ -77,39 +70,9 @@
           '#eadecd',
         ],
       },
-      colorSchemes_: {
-        type: Object,
-        readOnly: true,
-        value(): DynamicColorScheme[] {
-          return [
-            // TODO(254479725): Replace with colors fetched from the
-            // backend.
-            {
-              id: ColorScheme.kTonalSpot,
-              primaryColor: 'var(--google-blue-500)',
-              secondaryColor: 'var(--google-red-500)',
-              tertiaryColor: 'var(--google-green-500)',
-            },
-            {
-              id: ColorScheme.kNeutral,
-              primaryColor: 'var(--google-red-500)',
-              secondaryColor: 'var(--google-blue-500)',
-              tertiaryColor: 'var(--google-green-500)',
-            },
-            {
-              id: ColorScheme.kVibrant,
-              primaryColor: 'var(--google-green-500)',
-              secondaryColor: 'var(--google-red-500)',
-              tertiaryColor: 'var(--google-blue-500)',
-            },
-            {
-              id: ColorScheme.kExpressive,
-              primaryColor: 'var(--google-orange-500)',
-              secondaryColor: 'var(--google-red-500)',
-              tertiaryColor: 'var(--google-green-500)',
-            },
-          ];
-        },
+      sampleColorSchemes_: {
+        type: Array,
+        notify: true,
       },
       // The color scheme button currently highlighted by keyboard navigation.
       colorSchemeHighlightedButton_: {
@@ -130,7 +93,7 @@
   private staticColorSelected_: SkColor|null;
   private colorSchemeSelected_: ColorScheme|null;
   private staticColors_: string[];
-  private colorSchemes_: DynamicColorScheme[];
+  private sampleColorSchemes_: SampleColorScheme[];
   private colorSchemeHighlightedButton_: CrButtonElement;
   private staticColorHighlightedButton_: CrButtonElement;
 
@@ -147,6 +110,8 @@
         'staticColorSelected_', state => state.theme.staticColorSelected);
     this.watch<DynamicColorElement['colorSchemeSelected_']>(
         'colorSchemeSelected_', state => state.theme.colorSchemeSelected);
+    this.watch<DynamicColorElement['sampleColorSchemes_']>(
+        'sampleColorSchemes_', state => state.theme.sampleColorSchemes);
     this.updateFromStore();
     initializeDynamicColorData(getThemeProvider(), this.getStore());
   }
diff --git a/ash/webui/personalization_app/resources/js/theme/theme_actions.ts b/ash/webui/personalization_app/resources/js/theme/theme_actions.ts
index 4d5486a..b985d507 100644
--- a/ash/webui/personalization_app/resources/js/theme/theme_actions.ts
+++ b/ash/webui/personalization_app/resources/js/theme/theme_actions.ts
@@ -5,7 +5,7 @@
 import {Action} from 'chrome://resources/ash/common/store/store.js';
 import {SkColor} from 'chrome://resources/mojo/skia/public/mojom/skcolor.mojom-webui.js';
 
-import {ColorScheme} from '../personalization_app.mojom-webui.js';
+import {ColorScheme, SampleColorScheme} from '../personalization_app.mojom-webui.js';
 
 /**
  * @fileoverview Defines the actions to change theme state.
@@ -15,11 +15,13 @@
   SET_DARK_MODE_ENABLED = 'set_dark_mode_enabled',
   SET_COLOR_MODE_AUTO_SCHEDULE_ENABLED = 'set_color_mode_auto_schedule_enabled',
   SET_COLOR_SCHEME = 'set_color_scheme',
+  SET_SAMPLE_COLOR_SCHEMES = 'set_sample_color_schemes',
   SET_STATIC_COLOR = 'set_static_color',
 }
 
-export type ThemeActions = SetColorModeAutoScheduleAction|
-    SetDarkModeEnabledAction|SetColorSchemePrefAction|SetStaticColorPrefAction;
+export type ThemeActions =
+    SetColorModeAutoScheduleAction|SetDarkModeEnabledAction|
+    SetColorSchemeAction|SetSampleColorSchemesAction|SetStaticColorAction;
 
 export type SetDarkModeEnabledAction = Action&{
   name: ThemeActionName.SET_DARK_MODE_ENABLED,
@@ -31,12 +33,17 @@
   enabled: boolean,
 };
 
-export type SetColorSchemePrefAction = Action&{
+export type SetColorSchemeAction = Action&{
   name: ThemeActionName.SET_COLOR_SCHEME,
   colorScheme: ColorScheme,
 };
 
-export type SetStaticColorPrefAction = Action&{
+export type SetSampleColorSchemesAction = Action&{
+  name: ThemeActionName.SET_SAMPLE_COLOR_SCHEMES,
+  sampleColorSchemes: SampleColorScheme[],
+};
+
+export type SetStaticColorAction = Action&{
   name: ThemeActionName.SET_STATIC_COLOR,
   staticColor: SkColor | null,
 };
@@ -52,11 +59,16 @@
 }
 
 export function setColorSchemeAction(colorScheme: ColorScheme):
-    SetColorSchemePrefAction {
+    SetColorSchemeAction {
   return {name: ThemeActionName.SET_COLOR_SCHEME, colorScheme};
 }
 
+export function setSampleColorSchemesAction(
+    sampleColorSchemes: SampleColorScheme[]): SetSampleColorSchemesAction {
+  return {name: ThemeActionName.SET_SAMPLE_COLOR_SCHEMES, sampleColorSchemes};
+}
+
 export function setStaticColorAction(staticColor: SkColor|
-                                     null): SetStaticColorPrefAction {
+                                     null): SetStaticColorAction {
   return {name: ThemeActionName.SET_STATIC_COLOR, staticColor};
 }
diff --git a/ash/webui/personalization_app/resources/js/theme/theme_controller.ts b/ash/webui/personalization_app/resources/js/theme/theme_controller.ts
index e9ea45b..7dedf385 100644
--- a/ash/webui/personalization_app/resources/js/theme/theme_controller.ts
+++ b/ash/webui/personalization_app/resources/js/theme/theme_controller.ts
@@ -7,7 +7,7 @@
 import {ColorScheme, ThemeProviderInterface} from '../personalization_app.mojom-webui.js';
 import {PersonalizationStore} from '../personalization_store.js';
 
-import {setColorModeAutoScheduleEnabledAction, setColorSchemeAction, setDarkModeEnabledAction, setStaticColorAction} from './theme_actions.js';
+import {setColorModeAutoScheduleEnabledAction, setColorSchemeAction, setDarkModeEnabledAction, setSampleColorSchemesAction, setStaticColorAction} from './theme_actions.js';
 
 /**
  * @fileoverview contains all of the functions to interact with C++ side through
@@ -18,22 +18,29 @@
 export async function initializeData(
     provider: ThemeProviderInterface,
     store: PersonalizationStore): Promise<void> {
+  const [{enabled}, {darkModeEnabled}] = await Promise.all([
+    provider.isColorModeAutoScheduleEnabled(),
+    provider.isDarkModeEnabled(),
+  ]);
   store.beginBatchUpdate();
-  const {enabled} = await provider.isColorModeAutoScheduleEnabled();
-  store.dispatch(setColorModeAutoScheduleEnabledAction(enabled));
-  const {darkModeEnabled} = await provider.isDarkModeEnabled();
   store.dispatch(setDarkModeEnabledAction(darkModeEnabled));
+  store.dispatch(setColorModeAutoScheduleEnabledAction(enabled));
   store.endBatchUpdate();
 }
 
 export async function initializeDynamicColorData(
     provider: ThemeProviderInterface,
     store: PersonalizationStore): Promise<void> {
+  const [{staticColor}, {colorScheme}, {sampleColorSchemes}] =
+      await Promise.all([
+        provider.getStaticColor(),
+        provider.getColorScheme(),
+        provider.generateSampleColorSchemes(),
+      ]);
   store.beginBatchUpdate();
-  const {staticColor} = await provider.getStaticColor();
   store.dispatch(setStaticColorAction(staticColor));
-  const {colorScheme} = await provider.getColorScheme();
   store.dispatch(setColorSchemeAction(colorScheme));
+  store.dispatch(setSampleColorSchemesAction(sampleColorSchemes));
   store.endBatchUpdate();
 }
 
diff --git a/ash/webui/personalization_app/resources/js/theme/theme_reducers.ts b/ash/webui/personalization_app/resources/js/theme/theme_reducers.ts
index 9a9364e..e118f9b 100644
--- a/ash/webui/personalization_app/resources/js/theme/theme_reducers.ts
+++ b/ash/webui/personalization_app/resources/js/theme/theme_reducers.ts
@@ -42,6 +42,17 @@
   }
 }
 
+export function sampleColorSchemesReducer(
+    state: ThemeState['sampleColorSchemes'], action: Actions,
+    _: PersonalizationState): ThemeState['sampleColorSchemes'] {
+  switch (action.name) {
+    case ThemeActionName.SET_SAMPLE_COLOR_SCHEMES:
+      return action.sampleColorSchemes;
+    default:
+      return state;
+  }
+}
+
 export function staticColorSelectedReducer(
     state: ThemeState['staticColorSelected'], action: Actions,
     _: PersonalizationState): ThemeState['staticColorSelected'] {
@@ -58,5 +69,6 @@
       colorModeAutoScheduleEnabled: colorModeAutoScheduleEnabledReducer,
       darkModeEnabled: darkModeEnabledReducer,
       colorSchemeSelected: colorSchemeSelectedReducer,
+      sampleColorSchemes: sampleColorSchemesReducer,
       staticColorSelected: staticColorSelectedReducer,
     };
diff --git a/ash/webui/personalization_app/resources/js/theme/theme_state.ts b/ash/webui/personalization_app/resources/js/theme/theme_state.ts
index 51bad29..40d9ef7 100644
--- a/ash/webui/personalization_app/resources/js/theme/theme_state.ts
+++ b/ash/webui/personalization_app/resources/js/theme/theme_state.ts
@@ -4,7 +4,7 @@
 
 import {SkColor} from 'chrome://resources/mojo/skia/public/mojom/skcolor.mojom-webui.js';
 
-import {ColorScheme} from '../personalization_app.mojom-webui.js';
+import {ColorScheme, SampleColorScheme} from '../personalization_app.mojom-webui.js';
 
 /**
  * Stores theme related states.
@@ -13,6 +13,7 @@
   colorModeAutoScheduleEnabled: boolean|null;
   colorSchemeSelected: ColorScheme|null;
   darkModeEnabled: boolean|null;
+  sampleColorSchemes: SampleColorScheme[];
   staticColorSelected: SkColor|null;
 }
 
@@ -21,6 +22,7 @@
     colorModeAutoScheduleEnabled: null,
     colorSchemeSelected: null,
     darkModeEnabled: null,
+    sampleColorSchemes: [],
     staticColorSelected: null,
   };
 }
diff --git a/ash/webui/personalization_app/test/fake_personalization_app_theme_provider.cc b/ash/webui/personalization_app/test/fake_personalization_app_theme_provider.cc
index 5dc740e..78569f5 100644
--- a/ash/webui/personalization_app/test/fake_personalization_app_theme_provider.cc
+++ b/ash/webui/personalization_app/test/fake_personalization_app_theme_provider.cc
@@ -60,6 +60,12 @@
   std::move(callback).Run(ash::ColorScheme::kTonalSpot);
 }
 
+void FakePersonalizationAppThemeProvider::GenerateSampleColorSchemes(
+    GenerateSampleColorSchemesCallback callback) {
+  std::vector<ash::SampleColorScheme> samples;
+  std::move(callback).Run(samples);
+}
+
 void FakePersonalizationAppThemeProvider::GetStaticColor(
     GetStaticColorCallback callback) {
   std::move(callback).Run(SK_ColorBLUE);
diff --git a/ash/webui/personalization_app/test/fake_personalization_app_theme_provider.h b/ash/webui/personalization_app/test/fake_personalization_app_theme_provider.h
index 78969ca..addb36b3 100644
--- a/ash/webui/personalization_app/test/fake_personalization_app_theme_provider.h
+++ b/ash/webui/personalization_app/test/fake_personalization_app_theme_provider.h
@@ -53,6 +53,9 @@
 
   void GetStaticColor(GetStaticColorCallback callback) override;
 
+  void GenerateSampleColorSchemes(
+      GenerateSampleColorSchemesCallback callback) override;
+
   void IsDarkModeEnabled(IsDarkModeEnabledCallback callback) override;
 
   void IsColorModeAutoScheduleEnabled(
diff --git a/ash/webui/personalization_app/test/personalization_app_mojom_banned_browsertest_fixture.cc b/ash/webui/personalization_app/test/personalization_app_mojom_banned_browsertest_fixture.cc
index ad57b2f..061e1f7 100644
--- a/ash/webui/personalization_app/test/personalization_app_mojom_banned_browsertest_fixture.cc
+++ b/ash/webui/personalization_app/test/personalization_app_mojom_banned_browsertest_fixture.cc
@@ -107,6 +107,10 @@
               (bool enabled),
               (override));
   MOCK_METHOD(void,
+              GenerateSampleColorSchemes,
+              (GenerateSampleColorSchemesCallback callback),
+              (override));
+  MOCK_METHOD(void,
               GetColorScheme,
               (GetColorSchemeCallback callback),
               (override));
diff --git a/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider_unittest.cc b/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider_unittest.cc
index a48e5c0..3c66ba82 100644
--- a/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider_unittest.cc
+++ b/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider_unittest.cc
@@ -640,7 +640,7 @@
         EXPECT_TRUE(found_match);
       } else {
         const auto& text_accel =
-            info->layout_properties->get_text_accelerator()->text_accelerator;
+            info->layout_properties->get_text_accelerator()->parts;
         if (!TextAccelContainsReplacements(id)) {
           // Ambient accelerators that contain no replacements e.g., Drag the
           // link to the tab's address bar
@@ -803,11 +803,11 @@
   auto& bundle = ui::ResourceBundle::GetSharedInstance();
   int FAKE_RESOURCE_ID = 1;
   bundle.OverrideLocaleStringResource(FAKE_RESOURCE_ID, replacement_string_);
-  const auto parts = provider_->CreateTextAcceleratorProperties(
+  const auto text_accelerator = provider_->CreateTextAcceleratorProperties(
       {FAKE_RESOURCE_ID, replacements_});
-  EXPECT_EQ(expected_parts_.size(), parts->text_accelerator.size());
+  EXPECT_EQ(expected_parts_.size(), text_accelerator->parts.size());
   for (size_t i = 0; i < expected_parts_.size(); i++) {
-    ValidateTextAccelerators(expected_parts_[i], parts->text_accelerator[i]);
+    ValidateTextAccelerators(expected_parts_[i], text_accelerator->parts[i]);
   }
 }
 
diff --git a/ash/webui/shortcut_customization_ui/backend/accelerator_layout_table.cc b/ash/webui/shortcut_customization_ui/backend/accelerator_layout_table.cc
index c3cb8d1..f48c204ee 100644
--- a/ash/webui/shortcut_customization_ui/backend/accelerator_layout_table.cc
+++ b/ash/webui/shortcut_customization_ui/backend/accelerator_layout_table.cc
@@ -98,6 +98,7 @@
 const NonConfigurableActionsMap& GetNonConfigurableActionsMap() {
   static base::NoDestructor<NonConfigurableActionsMap>
       nonConfigurableActionsMap({
+          // Ambient Accelerator with replacement.
           {NonConfigurableActions::kBrowserSelectTabByIndex,
            NonConfigurableAcceleratorDetails(
                IDS_AMBIENT_ACCELERATOR_GO_TO_TAB_IN_RANGE,
@@ -105,6 +106,121 @@
                 TextAcceleratorPart(TextAcceleratorDelimiter::kPlusSign),
                 TextAcceleratorPart(ui::KeyboardCode::VKEY_1),
                 TextAcceleratorPart(ui::KeyboardCode::VKEY_8)})},
+          {NonConfigurableActions::kBrowserFindNext,
+           NonConfigurableAcceleratorDetails(
+               IDS_AMBIENT_ACCELERATOR_FIND_NEXT,
+               {TextAcceleratorPart(ui::EF_CONTROL_DOWN),
+                TextAcceleratorPart(ui::KeyboardCode::VKEY_G),
+                TextAcceleratorPart(ui::KeyboardCode::VKEY_RETURN)})},
+          {NonConfigurableActions::kBrowserFindPrevious,
+           NonConfigurableAcceleratorDetails(
+               IDS_AMBIENT_ACCELERATOR_FIND_PREVIOUS,
+               {TextAcceleratorPart(ui::EF_CONTROL_DOWN),
+                TextAcceleratorPart(ui::EF_SHIFT_DOWN),
+                TextAcceleratorPart(ui::KeyboardCode::VKEY_G),
+                TextAcceleratorPart(ui::EF_SHIFT_DOWN),
+                TextAcceleratorPart(ui::KeyboardCode::VKEY_RETURN)})},
+          {NonConfigurableActions::kAmbientOpenLinkInTab,
+           NonConfigurableAcceleratorDetails(
+               IDS_AMBIENT_ACCELERATOR_OPEN_LINK_IN_TAB,
+               {TextAcceleratorPart(ui::EF_CONTROL_DOWN),
+                TextAcceleratorPart(ui::EF_SHIFT_DOWN)})},
+          {NonConfigurableActions::kAmbientOpenLinkInTabBackground,
+           NonConfigurableAcceleratorDetails(
+               IDS_AMBIENT_ACCELERATOR_OPEN_LINK_IN_TAB_BACKGROUND,
+               {TextAcceleratorPart(ui::EF_CONTROL_DOWN)})},
+          {NonConfigurableActions::kAmbientOpenLinkInWindow,
+           NonConfigurableAcceleratorDetails(
+               IDS_AMBIENT_ACCELERATOR_OPEN_LINK_IN_WINDOW,
+               {TextAcceleratorPart(ui::EF_SHIFT_DOWN)})},
+          {NonConfigurableActions::kAmbientOpenPageInNewTab,
+           NonConfigurableAcceleratorDetails(
+               IDS_AMBIENT_ACCELERATOR_OPEN_PAGE_IN_NEW_TAB,
+               {TextAcceleratorPart(ui::EF_ALT_DOWN),
+                TextAcceleratorPart(ui::KeyboardCode::VKEY_RETURN)})},
+          {NonConfigurableActions::kAmbientCycleBackwardMRU,
+           NonConfigurableAcceleratorDetails(
+               IDS_AMBIENT_ACCELERATOR_CYCLE_BACKWARD_MRU,
+               {TextAcceleratorPart(ui::EF_ALT_DOWN),
+                TextAcceleratorPart(ui::EF_SHIFT_DOWN),
+                TextAcceleratorPart(ui::KeyboardCode::VKEY_TAB)})},
+          {NonConfigurableActions::kBrowserFocusSearch,
+           NonConfigurableAcceleratorDetails(
+               IDS_AMBIENT_ACCELERATOR_FOCUS_SEARCH,
+               {TextAcceleratorPart(ui::EF_CONTROL_DOWN),
+                TextAcceleratorPart(ui::KeyboardCode::VKEY_K),
+                TextAcceleratorPart(ui::KeyboardCode::VKEY_E)})},
+          {NonConfigurableActions::kBrowserReload,
+           NonConfigurableAcceleratorDetails(
+               IDS_AMBIENT_ACCELERATOR_RELOAD,
+               {TextAcceleratorPart(ui::KeyboardCode::VKEY_BROWSER_REFRESH),
+                TextAcceleratorPart(ui::EF_CONTROL_DOWN),
+                TextAcceleratorPart(ui::KeyboardCode::VKEY_R)})},
+          {NonConfigurableActions::kBrowserRightClick,
+           NonConfigurableAcceleratorDetails(
+               IDS_AMBIENT_ACCELERATOR_RIGHT_CLICK,
+               {TextAcceleratorPart(ui::EF_ALT_DOWN)})},
+          {NonConfigurableActions::kBrowserShowAppMenu,
+           NonConfigurableAcceleratorDetails(
+               IDS_AMBIENT_ACCELERATOR_SHOW_APP_MENU,
+               {TextAcceleratorPart(ui::EF_CONTROL_DOWN),
+                TextAcceleratorPart(ui::KeyboardCode::VKEY_E),
+                TextAcceleratorPart(ui::KeyboardCode::VKEY_F)})},
+          {NonConfigurableActions::kAmbientLaunchNumberedApp,
+           NonConfigurableAcceleratorDetails(
+               IDS_AMBIENT_ACCELERATOR_LAUNCH_NUMBERED_APP,
+               {TextAcceleratorPart(ui::EF_ALT_DOWN),
+                TextAcceleratorPart(TextAcceleratorDelimiter::kPlusSign),
+                TextAcceleratorPart(ui::KeyboardCode::VKEY_1),
+                TextAcceleratorPart(ui::KeyboardCode::VKEY_8)})},
+          {NonConfigurableActions::kAmbientOpenFile,
+           NonConfigurableAcceleratorDetails(
+               IDS_AMBIENT_ACCELERATOR_OPEN_FILE,
+               {TextAcceleratorPart(ui::KeyboardCode::VKEY_SPACE)})},
+          {NonConfigurableActions::kAmbientHighlightNextItemOnShelf,
+           NonConfigurableAcceleratorDetails(
+               IDS_AMBIENT_ACCELERATOR_HIGHLIGHT_NEXT_ITEM_ON_SHELF,
+               {TextAcceleratorPart(ui::EF_SHIFT_DOWN),
+                TextAcceleratorPart(ui::EF_ALT_DOWN),
+                TextAcceleratorPart(ui::KeyboardCode::VKEY_I),
+                TextAcceleratorPart(ui::KeyboardCode::VKEY_TAB),
+                TextAcceleratorPart(ui::KeyboardCode::VKEY_RIGHT)})},
+          {NonConfigurableActions::kAmbientHighlightPreviousItemOnShelf,
+           NonConfigurableAcceleratorDetails(
+               IDS_AMBIENT_ACCELERATOR_HIGHTLIGHT_PREVIOUS_ITEM_ON_SHELF,
+               {TextAcceleratorPart(ui::EF_SHIFT_DOWN),
+                TextAcceleratorPart(ui::EF_ALT_DOWN),
+                TextAcceleratorPart(ui::KeyboardCode::VKEY_I),
+                TextAcceleratorPart(ui::KeyboardCode::VKEY_TAB),
+                TextAcceleratorPart(ui::EF_SHIFT_DOWN),
+                TextAcceleratorPart(ui::KeyboardCode::VKEY_LEFT)})},
+          {NonConfigurableActions::kAmbientOpenHighlightedItemOnShelf,
+           NonConfigurableAcceleratorDetails(
+               IDS_AMBIENT_ACCELERATOR_OPEN_HIGHLIGHTED_ITEM_ON_SHELF,
+               {TextAcceleratorPart(ui::EF_SHIFT_DOWN),
+                TextAcceleratorPart(ui::EF_ALT_DOWN),
+                TextAcceleratorPart(ui::KeyboardCode::VKEY_I),
+                TextAcceleratorPart(ui::KeyboardCode::VKEY_SPACE),
+                TextAcceleratorPart(ui::KeyboardCode::VKEY_RETURN)})},
+          {NonConfigurableActions::kAmbientRemoveHighlightOnShelf,
+           NonConfigurableAcceleratorDetails(
+               IDS_AMBIENT_ACCELERATOR_REMOVE_HIGHLIGHT_ON_SHELF,
+               {TextAcceleratorPart(ui::EF_SHIFT_DOWN),
+                TextAcceleratorPart(ui::EF_ALT_DOWN),
+                TextAcceleratorPart(ui::KeyboardCode::VKEY_I),
+                TextAcceleratorPart(ui::KeyboardCode::VKEY_ESCAPE)})},
+          // Ambient accelerators that only contain plain text (no
+          // replacements).
+          {NonConfigurableActions::kAmbientDragLinkInNewTab,
+           NonConfigurableAcceleratorDetails(
+               IDS_AMBIENT_ACCELERATOR_DRAG_LINK_IN_NEW_TAB)},
+          {NonConfigurableActions::kAmbientDragLinkInSameTab,
+           NonConfigurableAcceleratorDetails(
+               IDS_AMBIENT_ACCELERATOR_DRAG_LINK_IN_SAME_TAB)},
+          {NonConfigurableActions::kAmbientSaveLinkAsBookmark,
+           NonConfigurableAcceleratorDetails(
+               IDS_AMBIENT_ACCELERATOR_SAVE_LINK_AS_BOOKMARK)},
+          // Standard accelerators.
           {NonConfigurableActions::kBrowserNewTab,
            NonConfigurableAcceleratorDetails(
                {ui::Accelerator(ui::VKEY_T, ui::EF_CONTROL_DOWN)})},
@@ -207,6 +323,30 @@
           {NonConfigurableActions::kBrowserFocusInactivePopupForAccessibility,
            NonConfigurableAcceleratorDetails({ui::Accelerator(
                ui::VKEY_A, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)})},
+          {NonConfigurableActions::kBrowserBottomPage,
+           NonConfigurableAcceleratorDetails(
+               {ui::Accelerator(ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN)})},
+          {NonConfigurableActions::kBrowserTopPage,
+           NonConfigurableAcceleratorDetails(
+               {ui::Accelerator(ui::VKEY_LEFT, ui::EF_COMMAND_DOWN)})},
+          {NonConfigurableActions::kBrowserNextPane,
+           NonConfigurableAcceleratorDetails({ui::Accelerator(
+               ui::VKEY_PRIOR, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN)})},
+          {NonConfigurableActions::kBrowserPageDown,
+           NonConfigurableAcceleratorDetails(
+               {ui::Accelerator(ui::VKEY_DOWN, ui::EF_COMMAND_DOWN)})},
+          {NonConfigurableActions::kBrowserPageUp,
+           NonConfigurableAcceleratorDetails(
+               {ui::Accelerator(ui::VKEY_UP, ui::EF_COMMAND_DOWN)})},
+          {NonConfigurableActions::kAmbientOpenRightClickMenu,
+           NonConfigurableAcceleratorDetails({ui::Accelerator(
+               ui::VKEY_VOLUME_UP, ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN)})},
+          {NonConfigurableActions::kAmbientDisplayHiddenFiles,
+           NonConfigurableAcceleratorDetails(
+               {ui::Accelerator(ui::VKEY_OEM_PERIOD, ui::EF_CONTROL_DOWN)})},
+          {NonConfigurableActions::kAmbientCaretBrowsing,
+           NonConfigurableAcceleratorDetails({ui::Accelerator(
+               ui::VKEY_7, ui::EF_CONTROL_DOWN | ui::EF_COMMAND_DOWN)})},
       });
   return *nonConfigurableActionsMap;
 }
diff --git a/ash/webui/shortcut_customization_ui/backend/accelerator_layout_table.h b/ash/webui/shortcut_customization_ui/backend/accelerator_layout_table.h
index 80fcbb6..34795d0f 100644
--- a/ash/webui/shortcut_customization_ui/backend/accelerator_layout_table.h
+++ b/ash/webui/shortcut_customization_ui/backend/accelerator_layout_table.h
@@ -69,6 +69,12 @@
   kBrowserFocusToolbar,
   kBrowserFocusInactivePopupForAccessibility,
   kBrowserSelectTabByIndex,
+  kBrowserBottomPage,
+  kBrowserTopPage,
+  kBrowserNextPane,
+  kBrowserPageUp,
+  kBrowserPageDown,
+  kBrowserRightClick,
   // Ambient action id
   kAmbientDragLinkInSameTab,
   kAmbientCycleForwardMRU,
@@ -89,6 +95,10 @@
   kAmbientMoveAppsInOutFolder,
   kAmbientRemoveHighlightOnShelf,
   kAmbientActivateIndexedDesk,
+  kAmbientLaunchAppByIndex,
+  kAmbientDisplayHiddenFiles,
+  kAmbientOpenRightClickMenu,
+  kAmbientCaretBrowsing
 };
 
 // Used to separate text accelerator parts in the UI e.g ctrl + 1.
@@ -299,6 +309,42 @@
      mojom::AcceleratorSubcategory::kGeneral,
      /*locked=*/true, mojom::AcceleratorLayoutStyle::kDefault,
      mojom::AcceleratorSource::kAmbient},
+    {NonConfigurableActions::kAmbientDragLinkInNewTab,
+     IDS_AMBIENT_ACCELERATOR_DESCRIPTION_DRAG_LINK_IN_NEW_TAB,
+     mojom::AcceleratorCategory::kTabsAndWindows,
+     mojom::AcceleratorSubcategory::kGeneral,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kText,
+     mojom::AcceleratorSource::kAmbient},
+    {NonConfigurableActions::kAmbientOpenLinkInTab,
+     IDS_AMBIENT_ACCELERATOR_DESCRIPTION_OPEN_LINK_IN_TAB,
+     mojom::AcceleratorCategory::kTabsAndWindows,
+     mojom::AcceleratorSubcategory::kGeneral,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kText,
+     mojom::AcceleratorSource::kAmbient},
+    {NonConfigurableActions::kAmbientDragLinkInSameTab,
+     IDS_AMBIENT_ACCELERATOR_DESCRIPTION_DRAG_LINK_IN_SAME_TAB,
+     mojom::AcceleratorCategory::kTabsAndWindows,
+     mojom::AcceleratorSubcategory::kGeneral,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kText,
+     mojom::AcceleratorSource::kAmbient},
+    {NonConfigurableActions::kAmbientOpenLinkInWindow,
+     IDS_AMBIENT_ACCELERATOR_DESCRIPTION_OPEN_LINK_IN_WINDOW,
+     mojom::AcceleratorCategory::kTabsAndWindows,
+     mojom::AcceleratorSubcategory::kGeneral,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kText,
+     mojom::AcceleratorSource::kAmbient},
+    {NonConfigurableActions::kAmbientOpenPageInNewTab,
+     IDS_AMBIENT_ACCELERATOR_DESCRIPTION_OPEN_PAGE_IN_NEW_TAB,
+     mojom::AcceleratorCategory::kTabsAndWindows,
+     mojom::AcceleratorSubcategory::kGeneral,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kText,
+     mojom::AcceleratorSource::kAmbient},
+    {NonConfigurableActions::kAmbientCycleBackwardMRU,
+     IDS_AMBIENT_ACCELERATOR_DESCRIPTION_CYCLE_BACKWARD_MRU,
+     mojom::AcceleratorCategory::kTabsAndWindows,
+     mojom::AcceleratorSubcategory::kGeneral,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kText,
+     mojom::AcceleratorSource::kAmbient},
     {NonConfigurableActions::kBrowserRestoreTab,
      IDS_BROWSER_ACCELERATOR_DESCRIPTION_RESTORE_TAB,
      mojom::AcceleratorCategory::kTabsAndWindows,
@@ -381,6 +427,55 @@
      mojom::AcceleratorSubcategory::kGeneral,
      /*locked=*/true, mojom::AcceleratorLayoutStyle::kDefault,
      mojom::AcceleratorSource::kAmbient},
+    {NonConfigurableActions::kBrowserBottomPage,
+     IDS_BROWSER_ACCELERATOR_DESCRIPTION_BOTTOM_PAGE,
+     mojom::AcceleratorCategory::kPageAndWebBrowser,
+     mojom::AcceleratorSubcategory::kGeneral,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kDefault,
+     mojom::AcceleratorSource::kAmbient},
+    {NonConfigurableActions::kBrowserFindNext,
+     IDS_BROWSER_ACCELERATOR_DESCRIPTION_FIND_NEXT,
+     mojom::AcceleratorCategory::kPageAndWebBrowser,
+     mojom::AcceleratorSubcategory::kGeneral,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kText,
+     mojom::AcceleratorSource::kAmbient},
+    {NonConfigurableActions::kBrowserFindPrevious,
+     IDS_BROWSER_ACCELERATOR_DESCRIPTION_FIND_PREVIOUS,
+     mojom::AcceleratorCategory::kPageAndWebBrowser,
+     mojom::AcceleratorSubcategory::kGeneral,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kText,
+     mojom::AcceleratorSource::kAmbient},
+    {NonConfigurableActions::kBrowserTopPage,
+     IDS_BROWSER_ACCELERATOR_DESCRIPTION_TOP_PAGE,
+     mojom::AcceleratorCategory::kPageAndWebBrowser,
+     mojom::AcceleratorSubcategory::kGeneral,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kDefault,
+     mojom::AcceleratorSource::kAmbient},
+    {NonConfigurableActions::kBrowserNextPane,
+     IDS_BROWSER_ACCELERATOR_DESCRIPTION_NEXT_PANE,
+     mojom::AcceleratorCategory::kPageAndWebBrowser,
+     mojom::AcceleratorSubcategory::kGeneral,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kDefault,
+     mojom::AcceleratorSource::kAmbient},
+    {NonConfigurableActions::kBrowserPageDown,
+     IDS_BROWSER_ACCELERATOR_DESCRIPTION_PAGE_DOWN,
+     mojom::AcceleratorCategory::kPageAndWebBrowser,
+     mojom::AcceleratorSubcategory::kGeneral,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kDefault,
+     mojom::AcceleratorSource::kAmbient},
+    {NonConfigurableActions::kBrowserPageUp,
+     IDS_BROWSER_ACCELERATOR_DESCRIPTION_PAGE_UP,
+     mojom::AcceleratorCategory::kPageAndWebBrowser,
+     mojom::AcceleratorSubcategory::kGeneral,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kDefault,
+     mojom::AcceleratorSource::kAmbient},
+    {NonConfigurableActions::kBrowserFocusSearch,
+     IDS_BROWSER_ACCELERATOR_DESCRIPTION_FOCUS_SEARCH,
+     mojom::AcceleratorCategory::kPageAndWebBrowser,
+     mojom::AcceleratorSubcategory::kGeneral,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kText,
+     mojom::AcceleratorSource::kAmbient},
+
     {NonConfigurableActions::kBrowserShowDownloads,
      IDS_BROWSER_ACCELERATOR_DESCRIPTION_SHOW_DOWNLOADS,
      mojom::AcceleratorCategory::kPageAndWebBrowser,
@@ -410,6 +505,12 @@
      mojom::AcceleratorSubcategory::kGeneral,
      /*locked=*/true, mojom::AcceleratorLayoutStyle::kDefault,
      mojom::AcceleratorSource::kAmbient},
+    {NonConfigurableActions::kBrowserReload,
+     IDS_BROWSER_ACCELERATOR_DESCRIPTION_RELOAD,
+     mojom::AcceleratorCategory::kPageAndWebBrowser,
+     mojom::AcceleratorSubcategory::kGeneral,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kText,
+     mojom::AcceleratorSource::kAmbient},
     {NonConfigurableActions::kBrowserReloadBypassingCache,
      IDS_BROWSER_ACCELERATOR_DESCRIPTION_RELOAD_BYPASSING_CACHE,
      mojom::AcceleratorCategory::kPageAndWebBrowser,
@@ -422,6 +523,18 @@
      mojom::AcceleratorSubcategory::kGeneral,
      /*locked=*/true, mojom::AcceleratorLayoutStyle::kDefault,
      mojom::AcceleratorSource::kAmbient},
+    {NonConfigurableActions::kBrowserRightClick,
+     IDS_BROWSER_ACCELERATOR_DESCRIPTION_RIGHT_CLICK,
+     mojom::AcceleratorCategory::kPageAndWebBrowser,
+     mojom::AcceleratorSubcategory::kGeneral,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kText,
+     mojom::AcceleratorSource::kAmbient},
+    {NonConfigurableActions::kAmbientSaveLinkAsBookmark,
+     IDS_AMBIENT_ACCELERATOR_DESCRIPTION_SAVE_LINK_AS_BOOKMARK,
+     mojom::AcceleratorCategory::kPageAndWebBrowser,
+     mojom::AcceleratorSubcategory::kGeneral,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kText,
+     mojom::AcceleratorSource::kAmbient},
     {NonConfigurableActions::kBrowserBookmarkAllTabs,
      IDS_BROWSER_ACCELERATOR_DESCRIPTION_BOOKMARK_ALL_TABS,
      mojom::AcceleratorCategory::kPageAndWebBrowser,
@@ -446,6 +559,12 @@
      mojom::AcceleratorSubcategory::kGeneral,
      /*locked=*/true, mojom::AcceleratorLayoutStyle::kDefault,
      mojom::AcceleratorSource::kAmbient},
+    {NonConfigurableActions::kBrowserShowAppMenu,
+     IDS_BROWSER_ACCELERATOR_DESCRIPTION_SHOW_APP_MENU,
+     mojom::AcceleratorCategory::kPageAndWebBrowser,
+     mojom::AcceleratorSubcategory::kGeneral,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kText,
+     mojom::AcceleratorSource::kAmbient},
     {NonConfigurableActions::kBrowserShowBookmarkManager,
      IDS_BROWSER_ACCELERATOR_DESCRIPTION_SHOW_BOOKMARK_MANAGER,
      mojom::AcceleratorCategory::kPageAndWebBrowser,
@@ -501,6 +620,12 @@
      mojom::AcceleratorSubcategory::kGeneral,
      /*locked=*/true, mojom::AcceleratorLayoutStyle::kDefault,
      mojom::AcceleratorSource::kAsh},
+    {NonConfigurableActions::kAmbientLaunchNumberedApp,
+     IDS_AMBIENT_ACCELERATOR_DESCRIPTION_LAUNCH_NUMBERED_APP,
+     mojom::AcceleratorCategory::kSystemAndDisplaySettings,
+     mojom::AcceleratorSubcategory::kGeneral,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kText,
+     mojom::AcceleratorSource::kAmbient},
     {LAUNCH_LAST_APP, IDS_ASH_ACCELERATOR_DESCRIPTION_LAUNCH_LAST_APP,
      mojom::AcceleratorCategory::kSystemAndDisplaySettings,
      mojom::AcceleratorSubcategory::kSystemControls,
@@ -516,6 +641,12 @@
      mojom::AcceleratorSubcategory::kGeneral,
      /*locked=*/true, mojom::AcceleratorLayoutStyle::kDefault,
      mojom::AcceleratorSource::kAsh},
+    {NonConfigurableActions::kAmbientDisplayHiddenFiles,
+     IDS_AMBIENT_ACCELERATOR_DESCRIPTION_DISPLAY_HIDDEN_FILES,
+     mojom::AcceleratorCategory::kSystemAndDisplaySettings,
+     mojom::AcceleratorSubcategory::kGeneral,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kDefault,
+     mojom::AcceleratorSource::kAmbient},
     {TOGGLE_MIRROR_MODE, IDS_ASH_ACCELERATOR_DESCRIPTION_TOGGLE_MIRROR_MODE,
      mojom::AcceleratorCategory::kSystemAndDisplaySettings,
      mojom::AcceleratorSubcategory::kGeneral,
@@ -552,6 +683,12 @@
      mojom::AcceleratorSubcategory::kSystemControls,
      /*locked=*/true, mojom::AcceleratorLayoutStyle::kDefault,
      mojom::AcceleratorSource::kAsh},
+    {NonConfigurableActions::kAmbientOpenFile,
+     IDS_AMBIENT_ACCELERATOR_DESCRIPTION_OPEN_FILE,
+     mojom::AcceleratorCategory::kSystemAndDisplaySettings,
+     mojom::AcceleratorSubcategory::kGeneral,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kText,
+     mojom::AcceleratorSource::kAmbient},
     {SUSPEND, IDS_ASH_ACCELERATOR_DESCRIPTION_SUSPEND,
      mojom::AcceleratorCategory::kSystemAndDisplaySettings,
      mojom::AcceleratorSubcategory::kGeneral,
@@ -723,6 +860,42 @@
      mojom::AcceleratorSubcategory::kSystemApps,
      /*locked=*/true, mojom::AcceleratorLayoutStyle::kDefault,
      mojom::AcceleratorSource::kAsh},
+    {NonConfigurableActions::kAmbientHighlightNextItemOnShelf,
+     IDS_AMBIENT_ACCELERATOR_DESCRIPTION_HIGHLIGHT_NEXT_ITEM_ON_SHELF,
+     mojom::AcceleratorCategory::kAccessibility,
+     mojom::AcceleratorSubcategory::kGeneral,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kText,
+     mojom::AcceleratorSource::kAmbient},
+    {NonConfigurableActions::kAmbientHighlightPreviousItemOnShelf,
+     IDS_AMBIENT_ACCELERATOR_DESCRIPTION_HIGHTLIGHT_PREVIOUS_ITEM_ON_SHELF,
+     mojom::AcceleratorCategory::kAccessibility,
+     mojom::AcceleratorSubcategory::kGeneral,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kText,
+     mojom::AcceleratorSource::kAmbient},
+    {NonConfigurableActions::kAmbientOpenRightClickMenu,
+     IDS_AMBIENT_ACCELERATOR_DESCRIPTION_OPEN_RIGHT_CLICK_MENU,
+     mojom::AcceleratorCategory::kAccessibility,
+     mojom::AcceleratorSubcategory::kSystemApps,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kDefault,
+     mojom::AcceleratorSource::kAmbient},
+    {NonConfigurableActions::kAmbientOpenHighlightedItemOnShelf,
+     IDS_AMBIENT_ACCELERATOR_DESCRIPTION_OPEN_HIGHLIGHTED_ITEM_ON_SHELF,
+     mojom::AcceleratorCategory::kAccessibility,
+     mojom::AcceleratorSubcategory::kSystemApps,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kText,
+     mojom::AcceleratorSource::kAmbient},
+    {NonConfigurableActions::kAmbientRemoveHighlightOnShelf,
+     IDS_AMBIENT_ACCELERATOR_DESCRIPTION_REMOVE_HIGHLIGHT_ON_SHELF,
+     mojom::AcceleratorCategory::kAccessibility,
+     mojom::AcceleratorSubcategory::kSystemApps,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kText,
+     mojom::AcceleratorSource::kAmbient},
+    {NonConfigurableActions::kAmbientCaretBrowsing,
+     IDS_AMBIENT_ACCELERATOR_DESCRIPTION_CARET_BROWSING,
+     mojom::AcceleratorCategory::kAccessibility,
+     mojom::AcceleratorSubcategory::kSystemApps,
+     /*locked=*/true, mojom::AcceleratorLayoutStyle::kDefault,
+     mojom::AcceleratorSource::kAmbient},
 };
 }  // namespace ash
 
diff --git a/ash/webui/shortcut_customization_ui/resources/js/accelerator_row.ts b/ash/webui/shortcut_customization_ui/resources/js/accelerator_row.ts
index b91b9f7..14e52d1 100644
--- a/ash/webui/shortcut_customization_ui/resources/js/accelerator_row.ts
+++ b/ash/webui/shortcut_customization_ui/resources/js/accelerator_row.ts
@@ -145,7 +145,7 @@
     assert(info.length === 1);
     const textAcceleratorInfo = info[0];
     assert(isTextAcceleratorInfo(textAcceleratorInfo));
-    return textAcceleratorInfo.layoutProperties.textAccelerator.textAccelerator;
+    return textAcceleratorInfo.layoutProperties.textAccelerator.parts;
   }
 
   static get template(): HTMLTemplateElement {
diff --git a/ash/webui/shortcut_customization_ui/resources/js/fake_data.ts b/ash/webui/shortcut_customization_ui/resources/js/fake_data.ts
index 2dffbfe..49f8817 100644
--- a/ash/webui/shortcut_customization_ui/resources/js/fake_data.ts
+++ b/ash/webui/shortcut_customization_ui/resources/js/fake_data.ts
@@ -37,7 +37,7 @@
   locked: true,
   layoutProperties: {
     textAccelerator: {
-      textAccelerator: [
+      parts: [
         {
           text: stringToMojoString16('ctrl'),
           type: TextAcceleratorPartType.kModifier,
diff --git a/ash/webui/shortcut_customization_ui/resources/js/shortcut_types.ts b/ash/webui/shortcut_customization_ui/resources/js/shortcut_types.ts
index e2c9199..ea4f1fd 100644
--- a/ash/webui/shortcut_customization_ui/resources/js/shortcut_types.ts
+++ b/ash/webui/shortcut_customization_ui/resources/js/shortcut_types.ts
@@ -98,8 +98,7 @@
 export type TextAcceleratorInfo =
     Omit<AcceleratorInfoTypes.AcceleratorInfo, 'layoutProperties'>&{
       layoutProperties: {
-        textAccelerator:
-            {textAccelerator: AcceleratorInfoTypes.TextAcceleratorPart[]},
+        textAccelerator: {parts: AcceleratorInfoTypes.TextAcceleratorPart[]},
       },
     };
 
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 7790861..9f50292 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -1319,8 +1319,6 @@
       "mac/scoped_objc_class_swizzler.mm",
       "mac/scoped_sending_event.h",
       "mac/scoped_sending_event.mm",
-      "mac/sdk_forward_declarations.h",
-      "mac/sdk_forward_declarations.mm",
       "message_loop/message_pump_mac.h",
       "message_loop/message_pump_mac.mm",
       "native_library_mac.mm",
diff --git a/base/allocator/partition_alloc_support.cc b/base/allocator/partition_alloc_support.cc
index 77fcf03..bc03424 100644
--- a/base/allocator/partition_alloc_support.cc
+++ b/base/allocator/partition_alloc_support.cc
@@ -23,13 +23,13 @@
 #include "base/allocator/partition_allocator/shim/allocator_shim.h"
 #include "base/allocator/partition_allocator/shim/allocator_shim_default_dispatch_to_partition_alloc.h"
 #include "base/allocator/partition_allocator/thread_cache.h"
-#include "base/bind.h"
-#include "base/callback.h"
 #include "base/check.h"
 #include "base/debug/dump_without_crashing.h"
 #include "base/debug/stack_trace.h"
 #include "base/debug/task_trace.h"
 #include "base/feature_list.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/immediate_crash.h"
 #include "base/location.h"
 #include "base/memory/raw_ptr_asan_service.h"
diff --git a/base/allocator/partition_allocator/shim/DEPS b/base/allocator/partition_allocator/shim/DEPS
index bd9aee3e..da271c5f 100644
--- a/base/allocator/partition_allocator/shim/DEPS
+++ b/base/allocator/partition_allocator/shim/DEPS
@@ -12,7 +12,7 @@
     "+base/allocator/partition_alloc_features.h",
     "+base/allocator/partition_allocator/partition_alloc_base",
     "+base/base_export.h",
-    "+base/bind.h",
+    "+base/functional/bind.h",
     "+base/logging.h",
     "+base/mac/mach_logging.h",
     "+base/memory/nonscannable_memory.h",
diff --git a/base/allocator/partition_allocator/shim/allocator_interception_mac.mm b/base/allocator/partition_allocator/shim/allocator_interception_mac.mm
index d476296..1db2f0cb 100644
--- a/base/allocator/partition_allocator/shim/allocator_interception_mac.mm
+++ b/base/allocator/partition_allocator/shim/allocator_interception_mac.mm
@@ -30,7 +30,7 @@
 #include "base/allocator/partition_allocator/partition_alloc_base/bits.h"
 #include "base/allocator/partition_allocator/partition_alloc_buildflags.h"
 #include "base/allocator/partition_allocator/shim/malloc_zone_functions_mac.h"
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/logging.h"
 #include "base/mac/mach_logging.h"
 #include "base/process/memory.h"
diff --git a/base/android/application_status_listener.cc b/base/android/application_status_listener.cc
index e8fb9f9d7..464343f 100644
--- a/base/android/application_status_listener.cc
+++ b/base/android/application_status_listener.cc
@@ -7,7 +7,7 @@
 #include <jni.h>
 
 #include "base/base_jni_headers/ApplicationStatus_jni.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/lazy_instance.h"
 #include "base/metrics/user_metrics.h"
 #include "base/observer_list_threadsafe.h"
diff --git a/base/android/application_status_listener.h b/base/android/application_status_listener.h
index 854b0e2..dbbc36b 100644
--- a/base/android/application_status_listener.h
+++ b/base/android/application_status_listener.h
@@ -10,7 +10,7 @@
 
 #include "base/android/jni_android.h"
 #include "base/base_export.h"
-#include "base/callback_forward.h"
+#include "base/functional/callback_forward.h"
 
 namespace base {
 namespace android {
diff --git a/base/android/application_status_listener_unittest.cc b/base/android/application_status_listener_unittest.cc
index c9629b542..224732c 100644
--- a/base/android/application_status_listener_unittest.cc
+++ b/base/android/application_status_listener_unittest.cc
@@ -6,7 +6,7 @@
 
 #include <memory>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/run_loop.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/test/task_environment.h"
diff --git a/base/android/base_jni_onload.cc b/base/android/base_jni_onload.cc
index df45b537..0b64a91 100644
--- a/base/android/base_jni_onload.cc
+++ b/base/android/base_jni_onload.cc
@@ -7,7 +7,7 @@
 #include "base/android/jni_android.h"
 #include "base/android/jni_utils.h"
 #include "base/android/library_loader/library_loader_hooks.h"
-#include "base/bind.h"
+#include "base/functional/bind.h"
 
 namespace base {
 namespace android {
diff --git a/base/android/base_jni_onload.h b/base/android/base_jni_onload.h
index c725db79..5f989033 100644
--- a/base/android/base_jni_onload.h
+++ b/base/android/base_jni_onload.h
@@ -8,7 +8,7 @@
 #include <jni.h>
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 
 namespace base {
 namespace android {
diff --git a/base/android/java_exception_reporter.cc b/base/android/java_exception_reporter.cc
index 2ebd181..395e976 100644
--- a/base/android/java_exception_reporter.cc
+++ b/base/android/java_exception_reporter.cc
@@ -8,9 +8,9 @@
 #include "base/android/jni_string.h"
 #include "base/android/scoped_java_ref.h"
 #include "base/base_jni_headers/JavaExceptionReporter_jni.h"
-#include "base/bind.h"
-#include "base/callback.h"
 #include "base/debug/dump_without_crashing.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/lazy_instance.h"
 
 using base::android::JavaParamRef;
diff --git a/base/android/java_exception_reporter.h b/base/android/java_exception_reporter.h
index 56baef75..50c3cab 100644
--- a/base/android/java_exception_reporter.h
+++ b/base/android/java_exception_reporter.h
@@ -9,7 +9,7 @@
 
 #include "base/android/scoped_java_ref.h"
 #include "base/base_export.h"
-#include "base/callback_forward.h"
+#include "base/functional/callback_forward.h"
 
 namespace base {
 namespace android {
diff --git a/base/android/java_handler_thread.cc b/base/android/java_handler_thread.cc
index 81a1c10..74fb75b 100644
--- a/base/android/java_handler_thread.cc
+++ b/base/android/java_handler_thread.cc
@@ -9,7 +9,7 @@
 #include "base/android/jni_android.h"
 #include "base/android/jni_string.h"
 #include "base/base_jni_headers/JavaHandlerThread_jni.h"
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/message_loop/message_pump.h"
 #include "base/message_loop/message_pump_type.h"
 #include "base/run_loop.h"
diff --git a/base/android/library_loader/library_loader_hooks.h b/base/android/library_loader/library_loader_hooks.h
index 8e16c952..52734aec 100644
--- a/base/android/library_loader/library_loader_hooks.h
+++ b/base/android/library_loader/library_loader_hooks.h
@@ -8,8 +8,8 @@
 #include <jni.h>
 
 #include "base/base_export.h"
-#include "base/callback.h"
 #include "base/command_line.h"
+#include "base/functional/callback.h"
 #include "base/metrics/field_trial.h"
 
 namespace base {
diff --git a/base/android/reached_code_profiler.cc b/base/android/reached_code_profiler.cc
index bf3767b..619cf95 100644
--- a/base/android/reached_code_profiler.cc
+++ b/base/android/reached_code_profiler.cc
@@ -15,12 +15,12 @@
 #include "base/android/orderfile/orderfile_buildflags.h"
 #include "base/android/reached_addresses_bitset.h"
 #include "base/base_switches.h"
-#include "base/bind.h"
 #include "base/command_line.h"
 #include "base/feature_list.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/important_file_writer.h"
+#include "base/functional/bind.h"
 #include "base/linux_util.h"
 #include "base/logging.h"
 #include "base/no_destructor.h"
diff --git a/base/android/task_scheduler/task_runner_android.cc b/base/android/task_scheduler/task_runner_android.cc
index 7371b21..304b8af 100644
--- a/base/android/task_scheduler/task_runner_android.cc
+++ b/base/android/task_scheduler/task_runner_android.cc
@@ -11,8 +11,8 @@
 #include "base/android/jni_string.h"
 #include "base/android_runtime_jni_headers/Runnable_jni.h"
 #include "base/base_jni_headers/TaskRunnerImpl_jni.h"
-#include "base/bind.h"
 #include "base/check.h"
+#include "base/functional/bind.h"
 #include "base/strings/strcat.h"
 #include "base/task/task_executor.h"
 #include "base/task/thread_pool/thread_pool_impl.h"
diff --git a/base/at_exit.cc b/base/at_exit.cc
index 69f1f42..a71988fc 100644
--- a/base/at_exit.cc
+++ b/base/at_exit.cc
@@ -8,9 +8,9 @@
 #include <ostream>
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback.h"
 #include "base/check_op.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/notreached.h"
 
 namespace base {
diff --git a/base/at_exit.h b/base/at_exit.h
index c68fad5..62e547a 100644
--- a/base/at_exit.h
+++ b/base/at_exit.h
@@ -6,9 +6,9 @@
 #define BASE_AT_EXIT_H_
 
 #include "base/base_export.h"
-#include "base/callback.h"
 #include "base/containers/stack.h"
 #include "base/dcheck_is_on.h"
+#include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/synchronization/lock.h"
 #include "base/thread_annotations.h"
diff --git a/base/at_exit_unittest.cc b/base/at_exit_unittest.cc
index 92c7ef1..3363cb0 100644
--- a/base/at_exit_unittest.cc
+++ b/base/at_exit_unittest.cc
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 #include "base/at_exit.h"
-#include "base/bind.h"
+#include "base/functional/bind.h"
 
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/base/barrier_callback.h b/base/barrier_callback.h
index c9d8af91..7738782 100644
--- a/base/barrier_callback.h
+++ b/base/barrier_callback.h
@@ -10,11 +10,11 @@
 #include <utility>
 #include <vector>
 
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
 #include "base/check.h"
 #include "base/check_op.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/synchronization/lock.h"
 #include "base/template_util.h"
 #include "base/thread_annotations.h"
diff --git a/base/barrier_callback_unittest.cc b/base/barrier_callback_unittest.cc
index fc934391..3d98940 100644
--- a/base/barrier_callback_unittest.cc
+++ b/base/barrier_callback_unittest.cc
@@ -4,8 +4,8 @@
 
 #include "base/barrier_callback.h"
 
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/test/bind.h"
 #include "base/test/gtest_util.h"
diff --git a/base/barrier_closure.cc b/base/barrier_closure.cc
index 2b4be53..613b46c 100644
--- a/base/barrier_closure.cc
+++ b/base/barrier_closure.cc
@@ -7,7 +7,7 @@
 #include <utility>
 
 #include "base/atomic_ref_count.h"
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/memory/ptr_util.h"
 #include "base/numerics/safe_conversions.h"
 
diff --git a/base/barrier_closure.h b/base/barrier_closure.h
index a88c475..e151946 100644
--- a/base/barrier_closure.h
+++ b/base/barrier_closure.h
@@ -6,7 +6,7 @@
 #define BASE_BARRIER_CLOSURE_H_
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 
 namespace base {
 
diff --git a/base/barrier_closure_unittest.cc b/base/barrier_closure_unittest.cc
index 47578db..98db45d8 100644
--- a/base/barrier_closure_unittest.cc
+++ b/base/barrier_closure_unittest.cc
@@ -4,9 +4,9 @@
 
 #include "base/barrier_closure.h"
 
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/raw_ptr.h"
 #include "base/test/bind.h"
 #include "base/test/gtest_util.h"
diff --git a/base/callback_list.cc b/base/callback_list.cc
index 53557f8..a50252e6 100644
--- a/base/callback_list.cc
+++ b/base/callback_list.cc
@@ -6,7 +6,7 @@
 
 #include <utility>
 
-#include "base/callback.h"
+#include "base/functional/callback.h"
 
 namespace base {
 
diff --git a/base/callback_list.h b/base/callback_list.h
index 72b7d03..bf1c0c5 100644
--- a/base/callback_list.h
+++ b/base/callback_list.h
@@ -11,11 +11,11 @@
 
 #include "base/auto_reset.h"
 #include "base/base_export.h"
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
 #include "base/check.h"
 #include "base/containers/cxx20_erase_list.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/weak_ptr.h"
 #include "base/ranges/algorithm.h"
 
diff --git a/base/callback_list_unittest.cc b/base/callback_list_unittest.cc
index 831a8d4..52fffc5 100644
--- a/base/callback_list_unittest.cc
+++ b/base/callback_list_unittest.cc
@@ -7,8 +7,8 @@
 #include <memory>
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/raw_ptr.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/base/callback_list_unittest.nc b/base/callback_list_unittest.nc
index dd93139..cc98db5 100644
--- a/base/callback_list_unittest.nc
+++ b/base/callback_list_unittest.nc
@@ -10,8 +10,8 @@
 #include <memory>
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 
 namespace base {
 
diff --git a/base/cancelable_callback.h b/base/cancelable_callback.h
index c4d4b3b0..73add8f 100644
--- a/base/cancelable_callback.h
+++ b/base/cancelable_callback.h
@@ -47,10 +47,10 @@
 
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback.h"
 #include "base/check.h"
 #include "base/compiler_specific.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/functional/callback_internal.h"
 #include "base/memory/weak_ptr.h"
 
diff --git a/base/cancelable_callback_unittest.cc b/base/cancelable_callback_unittest.cc
index 577a60d..ee6bac78 100644
--- a/base/cancelable_callback_unittest.cc
+++ b/base/cancelable_callback_unittest.cc
@@ -6,8 +6,8 @@
 
 #include <memory>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/location.h"
 #include "base/memory/ref_counted.h"
 #include "base/run_loop.h"
diff --git a/base/check_unittest.cc b/base/check_unittest.cc
index 32b6855..8a7a583 100644
--- a/base/check_unittest.cc
+++ b/base/check_unittest.cc
@@ -4,9 +4,9 @@
 
 #include <tuple>
 
-#include "base/bind.h"
-#include "base/callback.h"
 #include "base/check_deref.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/logging.h"
 #include "base/strings/string_piece.h"
 #include "base/test/gtest_util.h"
diff --git a/base/containers/intrusive_heap_unittest.cc b/base/containers/intrusive_heap_unittest.cc
index cdb64d1..63f8b3e 100644
--- a/base/containers/intrusive_heap_unittest.cc
+++ b/base/containers/intrusive_heap_unittest.cc
@@ -4,8 +4,8 @@
 
 #include "base/containers/intrusive_heap.h"
 
-#include "base/callback_helpers.h"
 #include "base/check_op.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/ptr_util.h"
 #include "base/notreached.h"
 #include "base/rand_util.h"
diff --git a/base/critical_closure.h b/base/critical_closure.h
index d25be8e6..228131e 100644
--- a/base/critical_closure.h
+++ b/base/critical_closure.h
@@ -7,13 +7,13 @@
 
 #include <utility>
 
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/location.h"
 #include "base/strings/string_piece.h"
 #include "build/build_config.h"
 
 #if BUILDFLAG(IS_IOS)
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/ios/scoped_critical_action.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #endif
diff --git a/base/debug/activity_analyzer_unittest.cc b/base/debug/activity_analyzer_unittest.cc
index 771c3471..414ab869 100644
--- a/base/debug/activity_analyzer_unittest.cc
+++ b/base/debug/activity_analyzer_unittest.cc
@@ -8,13 +8,13 @@
 #include <memory>
 
 #include "base/auto_reset.h"
-#include "base/bind.h"
 #include "base/containers/contains.h"
 #include "base/debug/activity_tracker.h"
 #include "base/files/file.h"
 #include "base/files/file_util.h"
 #include "base/files/memory_mapped_file.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/functional/bind.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/read_only_shared_memory_region.h"
diff --git a/base/debug/activity_tracker.h b/base/debug/activity_tracker.h
index 07c0ed51..f4160da 100644
--- a/base/debug/activity_tracker.h
+++ b/base/debug/activity_tracker.h
@@ -18,10 +18,10 @@
 #include <vector>
 
 #include "base/base_export.h"
-#include "base/callback.h"
 #include "base/compiler_specific.h"
 #include "base/containers/span.h"
 #include "base/dcheck_is_on.h"
+#include "base/functional/callback.h"
 #include "base/gtest_prod_util.h"
 #include "base/location.h"
 #include "base/memory/raw_ptr.h"
diff --git a/base/debug/activity_tracker_unittest.cc b/base/debug/activity_tracker_unittest.cc
index 317e4f5..8f1e16a 100644
--- a/base/debug/activity_tracker_unittest.cc
+++ b/base/debug/activity_tracker_unittest.cc
@@ -7,12 +7,12 @@
 #include <memory>
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/files/file.h"
 #include "base/files/file_util.h"
 #include "base/files/memory_mapped_file.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/pending_task.h"
diff --git a/base/files/file_descriptor_watcher_posix.cc b/base/files/file_descriptor_watcher_posix.cc
index 7529b15..06bf1dcc 100644
--- a/base/files/file_descriptor_watcher_posix.cc
+++ b/base/files/file_descriptor_watcher_posix.cc
@@ -6,8 +6,8 @@
 
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ref.h"
 #include "base/message_loop/message_pump_for_io.h"
diff --git a/base/files/file_descriptor_watcher_posix.h b/base/files/file_descriptor_watcher_posix.h
index f485ee73..21ec010 100644
--- a/base/files/file_descriptor_watcher_posix.h
+++ b/base/files/file_descriptor_watcher_posix.h
@@ -8,8 +8,8 @@
 #include <memory>
 
 #include "base/base_export.h"
-#include "base/callback.h"
 #include "base/dcheck_is_on.h"
+#include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/message_loop/message_pump_for_io.h"
diff --git a/base/files/file_descriptor_watcher_posix_unittest.cc b/base/files/file_descriptor_watcher_posix_unittest.cc
index 5645d7c..099f148 100644
--- a/base/files/file_descriptor_watcher_posix_unittest.cc
+++ b/base/files/file_descriptor_watcher_posix_unittest.cc
@@ -8,9 +8,9 @@
 
 #include <memory>
 
-#include "base/bind.h"
 #include "base/containers/span.h"
 #include "base/files/file_util.h"
+#include "base/functional/bind.h"
 #include "base/memory/ptr_util.h"
 #include "base/message_loop/message_pump_type.h"
 #include "base/posix/eintr_wrapper.h"
diff --git a/base/files/file_path_watcher.h b/base/files/file_path_watcher.h
index ac9f638..2f3a53a2 100644
--- a/base/files/file_path_watcher.h
+++ b/base/files/file_path_watcher.h
@@ -11,7 +11,7 @@
 #include <utility>
 
 #include "base/base_export.h"
-#include "base/callback_forward.h"
+#include "base/functional/callback_forward.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/sequence_checker.h"
 #include "base/task/sequenced_task_runner.h"
diff --git a/base/files/file_path_watcher_fsevents.cc b/base/files/file_path_watcher_fsevents.cc
index c4caff9..6c9461e 100644
--- a/base/files/file_path_watcher_fsevents.cc
+++ b/base/files/file_path_watcher_fsevents.cc
@@ -9,9 +9,9 @@
 #include <algorithm>
 #include <list>
 
-#include "base/bind.h"
 #include "base/check.h"
 #include "base/files/file_util.h"
+#include "base/functional/bind.h"
 #include "base/lazy_instance.h"
 #include "base/mac/scoped_cftyperef.h"
 #include "base/strings/stringprintf.h"
diff --git a/base/files/file_path_watcher_inotify.cc b/base/files/file_path_watcher_inotify.cc
index 89020b9..bf72568 100644
--- a/base/files/file_path_watcher_inotify.cc
+++ b/base/files/file_path_watcher_inotify.cc
@@ -23,12 +23,12 @@
 #include <utility>
 #include <vector>
 
-#include "base/bind.h"
 #include "base/containers/contains.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_path.h"
 #include "base/files/file_path_watcher_inotify.h"
 #include "base/files/file_util.h"
+#include "base/functional/bind.h"
 #include "base/lazy_instance.h"
 #include "base/location.h"
 #include "base/logging.h"
diff --git a/base/files/file_path_watcher_kqueue.cc b/base/files/file_path_watcher_kqueue.cc
index 98bc395..3e911fe1 100644
--- a/base/files/file_path_watcher_kqueue.cc
+++ b/base/files/file_path_watcher_kqueue.cc
@@ -11,9 +11,9 @@
 #include <string>
 #include <vector>
 
-#include "base/bind.h"
 #include "base/file_descriptor_posix.h"
 #include "base/files/file_util.h"
+#include "base/functional/bind.h"
 #include "base/logging.h"
 #include "base/ranges/algorithm.h"
 #include "base/strings/stringprintf.h"
diff --git a/base/files/file_path_watcher_unittest.cc b/base/files/file_path_watcher_unittest.cc
index 84c4377a..5165f3ec 100644
--- a/base/files/file_path_watcher_unittest.cc
+++ b/base/files/file_path_watcher_unittest.cc
@@ -9,11 +9,11 @@
 #include <string>
 #include <vector>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/run_loop.h"
diff --git a/base/files/file_path_watcher_win.cc b/base/files/file_path_watcher_win.cc
index 68700726..9b3f13c 100644
--- a/base/files/file_path_watcher_win.cc
+++ b/base/files/file_path_watcher_win.cc
@@ -6,10 +6,10 @@
 
 #include <windows.h>
 
-#include "base/bind.h"
 #include "base/files/file.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
+#include "base/functional/bind.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
diff --git a/base/files/file_proxy.cc b/base/files/file_proxy.cc
index 1209172..c3b8083 100644
--- a/base/files/file_proxy.cc
+++ b/base/files/file_proxy.cc
@@ -7,10 +7,10 @@
 #include <memory>
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/files/file.h"
 #include "base/files/file_util.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/location.h"
 #include "base/task/task_runner.h"
 
diff --git a/base/files/file_proxy.h b/base/files/file_proxy.h
index 6a6415c..680a511 100644
--- a/base/files/file_proxy.h
+++ b/base/files/file_proxy.h
@@ -8,9 +8,9 @@
 #include <stdint.h>
 
 #include "base/base_export.h"
-#include "base/callback_forward.h"
 #include "base/files/file.h"
 #include "base/files/file_path.h"
+#include "base/functional/callback_forward.h"
 #include "base/memory/weak_ptr.h"
 
 namespace base {
diff --git a/base/files/file_proxy_unittest.cc b/base/files/file_proxy_unittest.cc
index 1861e64..6ae91d1 100644
--- a/base/files/file_proxy_unittest.cc
+++ b/base/files/file_proxy_unittest.cc
@@ -9,10 +9,10 @@
 
 #include <utility>
 
-#include "base/bind.h"
 #include "base/files/file.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/functional/bind.h"
 #include "base/memory/weak_ptr.h"
 #include "base/run_loop.h"
 #include "base/test/task_environment.h"
diff --git a/base/files/file_util.h b/base/files/file_util.h
index ff8314a..7ec9f2b 100644
--- a/base/files/file_util.h
+++ b/base/files/file_util.h
@@ -17,11 +17,11 @@
 #include <string>
 
 #include "base/base_export.h"
-#include "base/callback.h"
 #include "base/containers/span.h"
 #include "base/files/file.h"
 #include "base/files/file_path.h"
 #include "base/files/scoped_file.h"
+#include "base/functional/callback.h"
 #include "build/build_config.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
diff --git a/base/files/file_util_unittest.cc b/base/files/file_util_unittest.cc
index 27cdb16..0a8b2997 100644
--- a/base/files/file_util_unittest.cc
+++ b/base/files/file_util_unittest.cc
@@ -17,8 +17,6 @@
 #include <vector>
 
 #include "base/base_paths.h"
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/command_line.h"
 #include "base/environment.h"
 #include "base/files/file.h"
@@ -27,6 +25,8 @@
 #include "base/files/platform_file.h"
 #include "base/files/scoped_file.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/guid.h"
 #include "base/logging.h"
 #include "base/path_service.h"
diff --git a/base/files/file_util_win.cc b/base/files/file_util_win.cc
index a00e013..c84124e 100644
--- a/base/files/file_util_win.cc
+++ b/base/files/file_util_win.cc
@@ -20,8 +20,6 @@
 #include <string>
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback.h"
 #include "base/clang_profiling_buildflags.h"
 #include "base/debug/alias.h"
 #include "base/feature_list.h"
@@ -29,6 +27,8 @@
 #include "base/files/file_enumerator.h"
 #include "base/files/file_path.h"
 #include "base/files/memory_mapped_file.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/guid.h"
 #include "base/location.h"
 #include "base/logging.h"
diff --git a/base/files/important_file_writer.cc b/base/files/important_file_writer.cc
index 1d53336..1eaedc5 100644
--- a/base/files/important_file_writer.cc
+++ b/base/files/important_file_writer.cc
@@ -12,8 +12,6 @@
 #include <string>
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/check.h"
 #include "base/critical_closure.h"
 #include "base/debug/alias.h"
@@ -21,6 +19,8 @@
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/important_file_writer_cleaner.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/logging.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/notreached.h"
diff --git a/base/files/important_file_writer.h b/base/files/important_file_writer.h
index 146e1c0..2c6a696 100644
--- a/base/files/important_file_writer.h
+++ b/base/files/important_file_writer.h
@@ -9,8 +9,8 @@
 #include <string>
 
 #include "base/base_export.h"
-#include "base/callback.h"
 #include "base/files/file_path.h"
+#include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/sequence_checker.h"
 #include "base/strings/string_piece.h"
diff --git a/base/files/important_file_writer_cleaner.cc b/base/files/important_file_writer_cleaner.cc
index 66841ce..46e1263 100644
--- a/base/files/important_file_writer_cleaner.cc
+++ b/base/files/important_file_writer_cleaner.cc
@@ -9,9 +9,9 @@
 #include <iterator>
 #include <utility>
 
-#include "base/bind.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_util.h"
+#include "base/functional/bind.h"
 #include "base/no_destructor.h"
 #include "base/process/process.h"
 #include "base/task/sequenced_task_runner.h"
diff --git a/base/files/important_file_writer_unittest.cc b/base/files/important_file_writer_unittest.cc
index 605cbd3..8d36b347 100644
--- a/base/files/important_file_writer_unittest.cc
+++ b/base/files/important_file_writer_unittest.cc
@@ -4,11 +4,11 @@
 
 #include "base/files/important_file_writer.h"
 
-#include "base/bind.h"
 #include "base/compiler_specific.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/functional/bind.h"
 #include "base/location.h"
 #include "base/memory/ptr_util.h"
 #include "base/notreached.h"
diff --git a/base/files/os_validation_win_unittest.cc b/base/files/os_validation_win_unittest.cc
index 8781cc7c..a380ee3 100644
--- a/base/files/os_validation_win_unittest.cc
+++ b/base/files/os_validation_win_unittest.cc
@@ -11,10 +11,10 @@
 #include <string>
 #include <tuple>
 
-#include "base/callback_helpers.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/string_util.h"
 #include "base/win/scoped_handle.h"
diff --git a/base/fuchsia/filtered_service_directory.cc b/base/fuchsia/filtered_service_directory.cc
index 5a831bc7..8115351 100644
--- a/base/fuchsia/filtered_service_directory.cc
+++ b/base/fuchsia/filtered_service_directory.cc
@@ -7,8 +7,8 @@
 #include <lib/async/default.h>
 #include <utility>
 
-#include "base/bind.h"
 #include "base/fuchsia/fuchsia_logging.h"
+#include "base/functional/bind.h"
 #include "base/strings/string_piece.h"
 
 namespace base {
diff --git a/base/fuchsia/intl_profile_watcher.h b/base/fuchsia/intl_profile_watcher.h
index 235105e..67adef8 100644
--- a/base/fuchsia/intl_profile_watcher.h
+++ b/base/fuchsia/intl_profile_watcher.h
@@ -9,7 +9,7 @@
 #include <string>
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/strings/string_piece_forward.h"
 
 namespace base {
diff --git a/base/fuchsia/process_lifecycle.h b/base/fuchsia/process_lifecycle.h
index 5b971da1..d8fed1b 100644
--- a/base/fuchsia/process_lifecycle.h
+++ b/base/fuchsia/process_lifecycle.h
@@ -9,7 +9,7 @@
 #include <lib/fidl/cpp/binding.h>
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 
 namespace base {
 
diff --git a/base/fuchsia/scoped_fx_logger.h b/base/fuchsia/scoped_fx_logger.h
index 77c9b71..9b96da0e 100644
--- a/base/fuchsia/scoped_fx_logger.h
+++ b/base/fuchsia/scoped_fx_logger.h
@@ -15,7 +15,7 @@
 #include <vector>
 
 #include "base/base_export.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 
 namespace base {
 
diff --git a/base/fuchsia/scoped_service_binding.h b/base/fuchsia/scoped_service_binding.h
index 3b146d9..41ac56c5 100644
--- a/base/fuchsia/scoped_service_binding.h
+++ b/base/fuchsia/scoped_service_binding.h
@@ -13,8 +13,8 @@
 #include <lib/zx/channel.h>
 
 #include "base/base_export.h"
-#include "base/callback.h"
 #include "base/fuchsia/scoped_service_publisher.h"
+#include "base/functional/callback.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace sys {
diff --git a/base/fuchsia/service_provider_impl.h b/base/fuchsia/service_provider_impl.h
index 31cd7c1..eef4663 100644
--- a/base/fuchsia/service_provider_impl.h
+++ b/base/fuchsia/service_provider_impl.h
@@ -15,7 +15,7 @@
 #include <string>
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 
 namespace sys {
 class OutgoingDirectory;
diff --git a/base/fuchsia/system_product_info_unittest.cc b/base/fuchsia/system_product_info_unittest.cc
index 540ea0f..8cd3f704 100644
--- a/base/fuchsia/system_product_info_unittest.cc
+++ b/base/fuchsia/system_product_info_unittest.cc
@@ -2,18 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/callback_forward.h"
 #include "base/fuchsia/system_info.h"
+#include "base/functional/callback_forward.h"
 
 #include <fuchsia/buildinfo/cpp/fidl.h>
 #include <fuchsia/hwinfo/cpp/fidl.h>
 #include <fuchsia/hwinfo/cpp/fidl_test_base.h>
 #include <memory>
 
-#include "base/bind.h"
 #include "base/fuchsia/scoped_service_binding.h"
 #include "base/fuchsia/scoped_service_publisher.h"
 #include "base/fuchsia/test_component_context_for_process.h"
+#include "base/functional/bind.h"
 #include "base/location.h"
 #include "base/run_loop.h"
 #include "base/strings/string_piece_forward.h"
diff --git a/base/fuchsia/test_log_listener_safe.cc b/base/fuchsia/test_log_listener_safe.cc
index 8f4b358..292c9e69 100644
--- a/base/fuchsia/test_log_listener_safe.cc
+++ b/base/fuchsia/test_log_listener_safe.cc
@@ -4,8 +4,8 @@
 
 #include "base/fuchsia/test_log_listener_safe.h"
 
-#include "base/callback_helpers.h"
 #include "base/fuchsia/fuchsia_logging.h"
+#include "base/functional/callback_helpers.h"
 #include "base/run_loop.h"
 #include "base/strings/string_piece.h"
 #include "base/test/bind.h"
diff --git a/base/fuchsia/test_log_listener_safe.h b/base/fuchsia/test_log_listener_safe.h
index d5b72976..f1e1a78 100644
--- a/base/fuchsia/test_log_listener_safe.h
+++ b/base/fuchsia/test_log_listener_safe.h
@@ -13,8 +13,8 @@
 #include <string>
 #include <vector>
 
-#include "base/callback.h"
 #include "base/containers/circular_deque.h"
+#include "base/functional/callback.h"
 #include "base/strings/string_piece.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
diff --git a/base/functional/callback.h b/base/functional/callback.h
index 5c4bf00..189259f 100644
--- a/base/functional/callback.h
+++ b/base/functional/callback.h
@@ -4,7 +4,7 @@
 //
 // NOTE: Header files that do not require the full definition of
 // base::{Once,Repeating}Callback or base::{Once,Repeating}Closure should
-// #include "base/callback_forward.h" instead of this file.
+// #include "base/functional/callback_forward.h" instead of this file.
 
 #ifndef BASE_FUNCTIONAL_CALLBACK_H_
 #define BASE_FUNCTIONAL_CALLBACK_H_
diff --git a/base/functional/function_ref_unittest.nc b/base/functional/function_ref_unittest.nc
index 927c778..72098e1 100644
--- a/base/functional/function_ref_unittest.nc
+++ b/base/functional/function_ref_unittest.nc
@@ -5,8 +5,8 @@
 // This is a "No Compile Test" suite.
 // http://dev.chromium.org/developers/testing/no-compile-tests
 
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/functional/function_ref.h"
 #include "third_party/abseil-cpp/absl/functional/function_ref.h"
 
diff --git a/base/i18n/streaming_utf8_validator_perftest.cc b/base/i18n/streaming_utf8_validator_perftest.cc
index 8d385f1..ac6a649 100644
--- a/base/i18n/streaming_utf8_validator_perftest.cc
+++ b/base/i18n/streaming_utf8_validator_perftest.cc
@@ -16,8 +16,8 @@
 
 #include <string>
 
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/test/perf_time_logger.h"
diff --git a/base/i18n/streaming_utf8_validator_unittest.cc b/base/i18n/streaming_utf8_validator_unittest.cc
index 770ceed..765edbb 100644
--- a/base/i18n/streaming_utf8_validator_unittest.cc
+++ b/base/i18n/streaming_utf8_validator_unittest.cc
@@ -11,7 +11,7 @@
 
 #include <string>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
diff --git a/base/ios/weak_nsobject_unittest.mm b/base/ios/weak_nsobject_unittest.mm
index 98dafbb..7414022 100644
--- a/base/ios/weak_nsobject_unittest.mm
+++ b/base/ios/weak_nsobject_unittest.mm
@@ -4,7 +4,7 @@
 
 #include "base/ios/weak_nsobject.h"
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/mac/scoped_nsobject.h"
 #include "base/run_loop.h"
 #include "base/task/single_thread_task_runner.h"
diff --git a/base/lazy_instance_unittest.cc b/base/lazy_instance_unittest.cc
index dfc9f404..89bdd5b4 100644
--- a/base/lazy_instance_unittest.cc
+++ b/base/lazy_instance_unittest.cc
@@ -12,8 +12,8 @@
 #include "base/atomic_sequence_num.h"
 #include "base/atomicops.h"
 #include "base/barrier_closure.h"
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/lazy_instance.h"
 #include "base/memory/aligned_memory.h"
 #include "base/memory/raw_ptr.h"
diff --git a/base/logging.cc b/base/logging.cc
index 1ec14b5..615b432 100644
--- a/base/logging.cc
+++ b/base/logging.cc
@@ -86,7 +86,6 @@
 #include <utility>
 
 #include "base/base_switches.h"
-#include "base/callback.h"
 #include "base/command_line.h"
 #include "base/containers/stack.h"
 #include "base/debug/activity_tracker.h"
@@ -94,6 +93,7 @@
 #include "base/debug/debugger.h"
 #include "base/debug/stack_trace.h"
 #include "base/debug/task_trace.h"
+#include "base/functional/callback.h"
 #include "base/no_destructor.h"
 #include "base/path_service.h"
 #include "base/posix/eintr_wrapper.h"
diff --git a/base/logging.h b/base/logging.h
index 50579d3..1ae198e 100644
--- a/base/logging.h
+++ b/base/logging.h
@@ -13,9 +13,9 @@
 #include <string>
 
 #include "base/base_export.h"
-#include "base/callback_forward.h"
 #include "base/compiler_specific.h"
 #include "base/dcheck_is_on.h"
+#include "base/functional/callback_forward.h"
 #include "base/logging_buildflags.h"
 #include "base/scoped_clear_last_error.h"
 #include "base/strings/string_piece_forward.h"
diff --git a/base/logging_unittest.cc b/base/logging_unittest.cc
index 6cfe45cb..3b17939 100644
--- a/base/logging_unittest.cc
+++ b/base/logging_unittest.cc
@@ -5,11 +5,11 @@
 #include <sstream>
 #include <string>
 
-#include "base/bind.h"
-#include "base/callback.h"
 #include "base/command_line.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/logging.h"
 #include "base/no_destructor.h"
 #include "base/process/process.h"
diff --git a/base/mac/OWNERS b/base/mac/OWNERS
index 093a9c8..a3fc32f 100644
--- a/base/mac/OWNERS
+++ b/base/mac/OWNERS
@@ -1,6 +1,2 @@
 mark@chromium.org
 thakis@chromium.org
-
-# sdk_forward_declarations.[h|mm] will likely need to be modified by Cocoa
-# developers in general.
-per-file sdk_forward_declarations.*=file://chrome/browser/ui/cocoa/OWNERS
diff --git a/base/mac/bind_objc_block_unittest.mm b/base/mac/bind_objc_block_unittest.mm
index aa8541c..04a34209c 100644
--- a/base/mac/bind_objc_block_unittest.mm
+++ b/base/mac/bind_objc_block_unittest.mm
@@ -4,9 +4,9 @@
 
 #include <string>
 
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/gtest_mac.h"
diff --git a/base/mac/bind_objc_block_unittest_arc.mm b/base/mac/bind_objc_block_unittest_arc.mm
index 2cda604..b14aa30 100644
--- a/base/mac/bind_objc_block_unittest_arc.mm
+++ b/base/mac/bind_objc_block_unittest_arc.mm
@@ -4,9 +4,9 @@
 
 #include <string>
 
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/gtest_mac.h"
diff --git a/base/mac/sdk_forward_declarations.h b/base/mac/sdk_forward_declarations.h
deleted file mode 100644
index 45f2730..0000000
--- a/base/mac/sdk_forward_declarations.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2012 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file contains forward declarations for items in later SDKs than the
-// default one with which Chromium is built.
-
-#ifndef BASE_MAC_SDK_FORWARD_DECLARATIONS_H_
-#define BASE_MAC_SDK_FORWARD_DECLARATIONS_H_
-
-#include <AvailabilityMacros.h>
-#include <AvailabilityVersions.h>
-#include <os/availability.h>
-
-// NOTE: If an #import is needed only for a newer SDK, it might be found below.
-
-#include "base/base_export.h"
-
-// ----------------------------------------------------------------------------
-// Definitions from SDKs newer than the one that Chromium compiles against.
-//
-// HOW TO DO THIS:
-//
-// 1. In this file:
-//   a. Use an #if !defined() guard
-//   b. Include all API_AVAILABLE/NS_CLASS_AVAILABLE_MAC annotations
-//   c. Optionally import frameworks
-// 2. In your source file:
-//   a. Correctly annotate availability with @available/__builtin_available/
-//      API_AVAILABLE
-//
-// This way, when the SDK is rolled, the section full of definitions
-// corresponding to it can be easily deleted.
-//
-// EXAMPLES OF HOW TO DO THIS:
-//
-// Suppose there's a simple extension of NSApplication in macOS 10.25. Then:
-//
-//   #if !defined(MAC_OS_X_VERSION_10_25) || \
-//       MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_25
-//
-//   @interface NSApplication (MacOSHouseCatSDK)
-//   @property(readonly) CGFloat purrRate API_AVAILABLE(macos(10.25));
-//   @end
-//
-//   #endif  // MAC_OS_X_VERSION_10_25
-//
-//
-// Suppose the CoreShoelace framework is introduced in macOS 10.77. Then:
-//
-//   #if !defined(MAC_OS_X_VERSION_10_77) || \
-//       MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_77
-//
-//   API_AVAILABLE(macos(10.77))
-//   @interface NSCoreShoelace : NSObject
-//   @property (readonly) NSUInteger stringLength;
-//   @end
-//
-//   #else
-//
-//   #import <CoreShoelace/CoreShoelace.h>
-//
-//   #endif  // MAC_OS_X_VERSION_10_77
-//
-// ----------------------------------------------------------------------------
-
-#endif  // BASE_MAC_SDK_FORWARD_DECLARATIONS_H_
diff --git a/base/mac/sdk_forward_declarations.mm b/base/mac/sdk_forward_declarations.mm
deleted file mode 100644
index d0c378146..0000000
--- a/base/mac/sdk_forward_declarations.mm
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2014 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/mac/sdk_forward_declarations.h"
-
-// ----------------------------------------------------------------------------
-// This file is reserved for the definition of any constant values declared in
-// sdk_forward_declarations.h.
-// ----------------------------------------------------------------------------
diff --git a/base/memory/discardable_memory_allocator.h b/base/memory/discardable_memory_allocator.h
index 6459281..f7a7605 100644
--- a/base/memory/discardable_memory_allocator.h
+++ b/base/memory/discardable_memory_allocator.h
@@ -10,7 +10,7 @@
 #include <memory>
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/memory/discardable_memory.h"
 
 namespace base {
diff --git a/base/memory/madv_free_discardable_memory_allocator_posix.h b/base/memory/madv_free_discardable_memory_allocator_posix.h
index 04d9b3b8..3e12720f 100644
--- a/base/memory/madv_free_discardable_memory_allocator_posix.h
+++ b/base/memory/madv_free_discardable_memory_allocator_posix.h
@@ -11,8 +11,8 @@
 #include <memory>
 
 #include "base/base_export.h"
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/memory/discardable_memory.h"
 #include "base/memory/discardable_memory_allocator.h"
 #include "base/memory/madv_free_discardable_memory_posix.h"
diff --git a/base/memory/madv_free_discardable_memory_posix.cc b/base/memory/madv_free_discardable_memory_posix.cc
index 051cc08..ffb6676d 100644
--- a/base/memory/madv_free_discardable_memory_posix.cc
+++ b/base/memory/madv_free_discardable_memory_posix.cc
@@ -14,7 +14,7 @@
 
 #include "base/atomicops.h"
 #include "base/bits.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/logging.h"
 #include "base/memory/madv_free_discardable_memory_allocator_posix.h"
 #include "base/memory/page_size.h"
diff --git a/base/memory/madv_free_discardable_memory_posix.h b/base/memory/madv_free_discardable_memory_posix.h
index 2cca982..bdee8b8 100644
--- a/base/memory/madv_free_discardable_memory_posix.h
+++ b/base/memory/madv_free_discardable_memory_posix.h
@@ -12,7 +12,7 @@
 #include <vector>
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/memory/discardable_memory.h"
 #include "base/memory/raw_ptr.h"
 #include "base/sequence_checker.h"
diff --git a/base/memory/madv_free_discardable_memory_posix_unittest.cc b/base/memory/madv_free_discardable_memory_posix_unittest.cc
index 4b0b2fd..11d54043a 100644
--- a/base/memory/madv_free_discardable_memory_posix_unittest.cc
+++ b/base/memory/madv_free_discardable_memory_posix_unittest.cc
@@ -8,10 +8,10 @@
 #include <sys/mman.h>
 #include <memory>
 
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
 #include "base/files/scoped_file.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/madv_free_discardable_memory_allocator_posix.h"
 #include "base/memory/madv_free_discardable_memory_posix.h"
 #include "base/memory/page_size.h"
diff --git a/base/memory/memory_pressure_listener.h b/base/memory/memory_pressure_listener.h
index 7cf058c..29e9364 100644
--- a/base/memory/memory_pressure_listener.h
+++ b/base/memory/memory_pressure_listener.h
@@ -11,7 +11,7 @@
 #define BASE_MEMORY_MEMORY_PRESSURE_LISTENER_H_
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/location.h"
 #include "base/tracing_buildflags.h"
 
diff --git a/base/memory/memory_pressure_listener_unittest.cc b/base/memory/memory_pressure_listener_unittest.cc
index 79d4be5..13232c9 100644
--- a/base/memory/memory_pressure_listener_unittest.cc
+++ b/base/memory/memory_pressure_listener_unittest.cc
@@ -4,7 +4,7 @@
 
 #include "base/memory/memory_pressure_listener.h"
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/run_loop.h"
 #include "base/test/task_environment.h"
 #include "testing/gmock/include/gmock/gmock.h"
diff --git a/base/memory/memory_pressure_monitor.h b/base/memory/memory_pressure_monitor.h
index 10b5895..3e5401b 100644
--- a/base/memory/memory_pressure_monitor.h
+++ b/base/memory/memory_pressure_monitor.h
@@ -6,7 +6,7 @@
 #define BASE_MEMORY_MEMORY_PRESSURE_MONITOR_H_
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/memory/memory_pressure_listener.h"
 #include "base/time/time.h"
 
diff --git a/base/memory/raw_ptr_unittest.nc b/base/memory/raw_ptr_unittest.nc
index 2f2ac6e..ba54d7b 100644
--- a/base/memory/raw_ptr_unittest.nc
+++ b/base/memory/raw_ptr_unittest.nc
@@ -9,8 +9,8 @@
 #include <tuple>  // for std::ignore
 #include <type_traits>  // for std::remove_pointer_t
 
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 
 namespace {
diff --git a/base/memory/safe_ref_unittest.cc b/base/memory/safe_ref_unittest.cc
index 19a8054..e5887013 100644
--- a/base/memory/safe_ref_unittest.cc
+++ b/base/memory/safe_ref_unittest.cc
@@ -6,8 +6,8 @@
 
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/memory/weak_ptr.h"
 #include "base/test/gtest_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/memory/weak_ptr_unittest.cc b/base/memory/weak_ptr_unittest.cc
index 5a6c873..869fed3 100644
--- a/base/memory/weak_ptr_unittest.cc
+++ b/base/memory/weak_ptr_unittest.cc
@@ -7,8 +7,8 @@
 #include <memory>
 #include <string>
 
-#include "base/bind.h"
 #include "base/debug/leak_annotations.h"
+#include "base/functional/bind.h"
 #include "base/location.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/task/single_thread_task_runner.h"
diff --git a/base/message_loop/fd_watch_controller_posix_unittest.cc b/base/message_loop/fd_watch_controller_posix_unittest.cc
index 70f7240..766f3926 100644
--- a/base/message_loop/fd_watch_controller_posix_unittest.cc
+++ b/base/message_loop/fd_watch_controller_posix_unittest.cc
@@ -5,10 +5,10 @@
 
 #include <sys/socket.h>
 
-#include "base/bind.h"
 #include "base/compiler_specific.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_file.h"
+#include "base/functional/bind.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/message_loop/message_pump_for_io.h"
diff --git a/base/message_loop/message_pump_android.cc b/base/message_loop/message_pump_android.cc
index 645a192..eb8e8976 100644
--- a/base/message_loop/message_pump_android.cc
+++ b/base/message_loop/message_pump_android.cc
@@ -17,8 +17,8 @@
 
 #include "base/android/jni_android.h"
 #include "base/android/scoped_java_ref.h"
-#include "base/callback_helpers.h"
 #include "base/check_op.h"
+#include "base/functional/callback_helpers.h"
 #include "base/lazy_instance.h"
 #include "base/notreached.h"
 #include "base/numerics/safe_conversions.h"
diff --git a/base/message_loop/message_pump_android.h b/base/message_loop/message_pump_android.h
index d28bd2e..0c8fe97 100644
--- a/base/message_loop/message_pump_android.h
+++ b/base/message_loop/message_pump_android.h
@@ -11,8 +11,8 @@
 
 #include "base/android/scoped_java_ref.h"
 #include "base/base_export.h"
-#include "base/callback.h"
 #include "base/compiler_specific.h"
+#include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/message_loop/message_pump.h"
 #include "base/time/time.h"
diff --git a/base/message_loop/message_pump_glib_unittest.cc b/base/message_loop/message_pump_glib_unittest.cc
index b41443c..b202b40 100644
--- a/base/message_loop/message_pump_glib_unittest.cc
+++ b/base/message_loop/message_pump_glib_unittest.cc
@@ -10,10 +10,10 @@
 #include <algorithm>
 #include <vector>
 
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
 #include "base/files/file_util.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
diff --git a/base/message_loop/message_pump_kqueue_unittest.cc b/base/message_loop/message_pump_kqueue_unittest.cc
index 96a2f2f..49712c3 100644
--- a/base/message_loop/message_pump_kqueue_unittest.cc
+++ b/base/message_loop/message_pump_kqueue_unittest.cc
@@ -9,7 +9,7 @@
 
 #include <utility>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
diff --git a/base/message_loop/message_pump_libevent_unittest.cc b/base/message_loop/message_pump_libevent_unittest.cc
index c8297122..f163b8b 100644
--- a/base/message_loop/message_pump_libevent_unittest.cc
+++ b/base/message_loop/message_pump_libevent_unittest.cc
@@ -9,10 +9,10 @@
 #include <memory>
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/containers/span.h"
 #include "base/files/file_util.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
diff --git a/base/message_loop/message_pump_mac_unittest.mm b/base/message_loop/message_pump_mac_unittest.mm
index d92a172f..24aeb79 100644
--- a/base/message_loop/message_pump_mac_unittest.mm
+++ b/base/message_loop/message_pump_mac_unittest.mm
@@ -4,8 +4,8 @@
 
 #include "base/message_loop/message_pump_mac.h"
 
-#include "base/bind.h"
 #include "base/cancelable_callback.h"
+#include "base/functional/bind.h"
 #include "base/mac/scoped_cftyperef.h"
 #import "base/mac/scoped_nsobject.h"
 #include "base/task/current_thread.h"
diff --git a/base/message_loop/message_pump_perftest.cc b/base/message_loop/message_pump_perftest.cc
index c5d7c4a..ae64cf1 100644
--- a/base/message_loop/message_pump_perftest.cc
+++ b/base/message_loop/message_pump_perftest.cc
@@ -7,9 +7,9 @@
 
 #include <memory>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/format_macros.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/ptr_util.h"
 #include "base/message_loop/message_pump_type.h"
 #include "base/strings/stringprintf.h"
diff --git a/base/message_loop/message_pump_unittest.cc b/base/message_loop/message_pump_unittest.cc
index 11c40c32..c650388 100644
--- a/base/message_loop/message_pump_unittest.cc
+++ b/base/message_loop/message_pump_unittest.cc
@@ -6,7 +6,7 @@
 
 #include <type_traits>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/logging.h"
 #include "base/memory/raw_ptr.h"
 #include "base/message_loop/message_pump_for_io.h"
diff --git a/base/message_loop/message_pump_win.cc b/base/message_loop/message_pump_win.cc
index 5d6cbbd..e0969d4 100644
--- a/base/message_loop/message_pump_win.cc
+++ b/base/message_loop/message_pump_win.cc
@@ -9,10 +9,10 @@
 #include <type_traits>
 
 #include "base/auto_reset.h"
-#include "base/bind.h"
 #include "base/cxx17_backports.h"
 #include "base/debug/alias.h"
 #include "base/feature_list.h"
+#include "base/functional/bind.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/trace_event/base_tracing.h"
diff --git a/base/message_loop/work_id_provider_unittest.cc b/base/message_loop/work_id_provider_unittest.cc
index 3b4ab0f..d5e70c1 100644
--- a/base/message_loop/work_id_provider_unittest.cc
+++ b/base/message_loop/work_id_provider_unittest.cc
@@ -8,7 +8,7 @@
 #include <memory>
 #include <utility>
 
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/test/bind.h"
 #include "base/threading/simple_thread.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/metrics/statistics_recorder.h b/base/metrics/statistics_recorder.h
index 8a6b324..8fd580dd 100644
--- a/base/metrics/statistics_recorder.h
+++ b/base/metrics/statistics_recorder.h
@@ -20,7 +20,7 @@
 #include <vector>
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/gtest_prod_util.h"
 #include "base/lazy_instance.h"
 #include "base/memory/raw_ptr.h"
diff --git a/base/metrics/statistics_recorder_unittest.cc b/base/metrics/statistics_recorder_unittest.cc
index 6a01878..9887829 100644
--- a/base/metrics/statistics_recorder_unittest.cc
+++ b/base/metrics/statistics_recorder_unittest.cc
@@ -10,7 +10,7 @@
 #include <utility>
 #include <vector>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/json/json_reader.h"
 #include "base/logging.h"
 #include "base/memory/weak_ptr.h"
diff --git a/base/metrics/user_metrics.cc b/base/metrics/user_metrics.cc
index ce4f834..cb55bfc 100644
--- a/base/metrics/user_metrics.cc
+++ b/base/metrics/user_metrics.cc
@@ -8,7 +8,7 @@
 
 #include <vector>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/lazy_instance.h"
 #include "base/location.h"
 #include "base/ranges/algorithm.h"
diff --git a/base/metrics/user_metrics.h b/base/metrics/user_metrics.h
index c6f5039..8181559 100644
--- a/base/metrics/user_metrics.h
+++ b/base/metrics/user_metrics.h
@@ -8,7 +8,7 @@
 #include <string>
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/metrics/user_metrics_action.h"
 #include "base/task/single_thread_task_runner.h"
 
diff --git a/base/no_destructor_unittest.cc b/base/no_destructor_unittest.cc
index 637e652..9dc2152 100644
--- a/base/no_destructor_unittest.cc
+++ b/base/no_destructor_unittest.cc
@@ -11,8 +11,8 @@
 
 #include "base/atomicops.h"
 #include "base/barrier_closure.h"
-#include "base/bind.h"
 #include "base/check.h"
+#include "base/functional/bind.h"
 #include "base/system/sys_info.h"
 #include "base/threading/platform_thread.h"
 #include "base/threading/simple_thread.h"
diff --git a/base/observer_list.h b/base/observer_list.h
index 6cbdec1..ae1acac 100644
--- a/base/observer_list.h
+++ b/base/observer_list.h
@@ -22,6 +22,7 @@
 #include "base/observer_list_internal.h"
 #include "base/ranges/algorithm.h"
 #include "base/sequence_checker.h"
+#include "build/build_config.h"
 
 ///////////////////////////////////////////////////////////////////////////////
 //
@@ -341,6 +342,9 @@
   std::string GetObserversCreationStackString() const {
 #if DCHECK_IS_ON()
     std::string result;
+#if BUILDFLAG(IS_IOS)
+    result += "Use go/observer-list-empty to interpret.\n";
+#endif
     for (const auto& observer : observers_) {
       result += observer.GetCreationStackString();
       result += "\n";
diff --git a/base/observer_list_threadsafe.h b/base/observer_list_threadsafe.h
index 9bc7ba0..98d53a44 100644
--- a/base/observer_list_threadsafe.h
+++ b/base/observer_list_threadsafe.h
@@ -9,7 +9,6 @@
 #include <utility>
 
 #include "base/base_export.h"
-#include "base/bind.h"
 #include "base/check.h"
 #include "base/check_op.h"
 #include "base/containers/contains.h"
diff --git a/base/observer_list_threadsafe_unittest.cc b/base/observer_list_threadsafe_unittest.cc
index e573e28..9514546e 100644
--- a/base/observer_list_threadsafe_unittest.cc
+++ b/base/observer_list_threadsafe_unittest.cc
@@ -7,8 +7,8 @@
 #include <memory>
 #include <vector>
 
-#include "base/bind.h"
 #include "base/compiler_specific.h"
+#include "base/functional/bind.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/memory/raw_ptr.h"
diff --git a/base/one_shot_event.cc b/base/one_shot_event.cc
index 132a079..051d63ad 100644
--- a/base/one_shot_event.cc
+++ b/base/one_shot_event.cc
@@ -7,7 +7,7 @@
 #include <stddef.h>
 #include <utility>
 
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/location.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/task/task_runner.h"
diff --git a/base/one_shot_event.h b/base/one_shot_event.h
index 43330d4..2c5753a 100644
--- a/base/one_shot_event.h
+++ b/base/one_shot_event.h
@@ -8,8 +8,8 @@
 #include <vector>
 
 #include "base/base_export.h"
-#include "base/callback_forward.h"
 #include "base/check.h"
+#include "base/functional/callback_forward.h"
 #include "base/memory/weak_ptr.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/threading/thread_checker.h"
diff --git a/base/one_shot_event_unittest.cc b/base/one_shot_event_unittest.cc
index ea82adb..e187a91 100644
--- a/base/one_shot_event_unittest.cc
+++ b/base/one_shot_event_unittest.cc
@@ -4,7 +4,7 @@
 
 #include "base/one_shot_event.h"
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
 #include "base/task/single_thread_task_runner.h"
diff --git a/base/pending_task.h b/base/pending_task.h
index 1df5474..aa95a6b 100644
--- a/base/pending_task.h
+++ b/base/pending_task.h
@@ -8,7 +8,7 @@
 #include <array>
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/location.h"
 #include "base/task/delay_policy.h"
 #include "base/time/time.h"
diff --git a/base/posix/unix_domain_socket_unittest.cc b/base/posix/unix_domain_socket_unittest.cc
index 7af2215..9f716e17c 100644
--- a/base/posix/unix_domain_socket_unittest.cc
+++ b/base/posix/unix_domain_socket_unittest.cc
@@ -10,10 +10,10 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_file.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/location.h"
 #include "base/pickle.h"
 #include "base/posix/unix_domain_socket.h"
diff --git a/base/power_monitor/battery_level_provider.h b/base/power_monitor/battery_level_provider.h
index 9ce92a4..7c5f969 100644
--- a/base/power_monitor/battery_level_provider.h
+++ b/base/power_monitor/battery_level_provider.h
@@ -9,7 +9,7 @@
 #include <memory>
 #include <vector>
 
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/base/power_monitor/iopm_power_source_sampling_event_source.h b/base/power_monitor/iopm_power_source_sampling_event_source.h
index 037d7b0..691d9b5 100644
--- a/base/power_monitor/iopm_power_source_sampling_event_source.h
+++ b/base/power_monitor/iopm_power_source_sampling_event_source.h
@@ -6,7 +6,7 @@
 #define BASE_POWER_MONITOR_IOPM_POWER_SOURCE_SAMPLING_EVENT_SOURCE_H_
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/mac/scoped_ionotificationportref.h"
 #include "base/mac/scoped_ioobject.h"
 #include "base/power_monitor/sampling_event_source.h"
diff --git a/base/power_monitor/sampling_event_source.h b/base/power_monitor/sampling_event_source.h
index f4114ed..8cee81c 100644
--- a/base/power_monitor/sampling_event_source.h
+++ b/base/power_monitor/sampling_event_source.h
@@ -6,7 +6,7 @@
 #define BASE_POWER_MONITOR_SAMPLING_EVENT_SOURCE_H_
 
 #include "base/base_export.h"
-#include "base/callback_forward.h"
+#include "base/functional/callback_forward.h"
 
 namespace base {
 
diff --git a/base/power_monitor/speed_limit_observer_win.h b/base/power_monitor/speed_limit_observer_win.h
index b157353..aefd887 100644
--- a/base/power_monitor/speed_limit_observer_win.h
+++ b/base/power_monitor/speed_limit_observer_win.h
@@ -6,7 +6,7 @@
 #define BASE_POWER_MONITOR_SPEED_LIMIT_OBSERVER_WIN_H_
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/power_monitor/moving_average.h"
 #include "base/power_monitor/power_observer.h"
 #include "base/time/time.h"
diff --git a/base/power_monitor/thermal_state_observer_mac.h b/base/power_monitor/thermal_state_observer_mac.h
index 73a1afa9..97ae1bd 100644
--- a/base/power_monitor/thermal_state_observer_mac.h
+++ b/base/power_monitor/thermal_state_observer_mac.h
@@ -10,7 +10,7 @@
 
 #include <IOKit/pwr_mgt/IOPMLib.h>
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/gtest_prod_util.h"
 #include "base/power_monitor/power_observer.h"
 
diff --git a/base/power_monitor/thermal_state_observer_mac_unittest.mm b/base/power_monitor/thermal_state_observer_mac_unittest.mm
index 9eb97e1..5da640f 100644
--- a/base/power_monitor/thermal_state_observer_mac_unittest.mm
+++ b/base/power_monitor/thermal_state_observer_mac_unittest.mm
@@ -10,7 +10,7 @@
 #include <memory>
 #include <queue>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/logging.h"
 #include "base/power_monitor/power_monitor.h"
 #include "base/power_monitor/power_monitor_source.h"
diff --git a/base/process/kill.cc b/base/process/kill.cc
index 6f771d86..bbee81a 100644
--- a/base/process/kill.cc
+++ b/base/process/kill.cc
@@ -4,7 +4,7 @@
 
 #include "base/process/kill.h"
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/process/process_iterator.h"
 #include "base/task/thread_pool.h"
 #include "base/time/time.h"
diff --git a/base/process/launch_win.cc b/base/process/launch_win.cc
index 88794788..615d74d1 100644
--- a/base/process/launch_win.cc
+++ b/base/process/launch_win.cc
@@ -17,10 +17,10 @@
 #include <ios>
 #include <limits>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/debug/activity_tracker.h"
 #include "base/debug/stack_trace.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/logging.h"
 #include "base/metrics/histogram.h"
 #include "base/process/environment_internal.h"
diff --git a/base/process/process_linux.cc b/base/process/process_linux.cc
index 5b98893..258061c 100644
--- a/base/process/process_linux.cc
+++ b/base/process/process_linux.cc
@@ -26,10 +26,10 @@
 #include "build/chromeos_buildflags.h"
 
 #if BUILDFLAG(IS_CHROMEOS)
-#include "base/bind.h"
 #include "base/feature_list.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_path.h"
+#include "base/functional/bind.h"
 #include "base/process/process_handle.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_util.h"
diff --git a/base/process/process_metrics_unittest.cc b/base/process/process_metrics_unittest.cc
index 798816a..3cc116f 100644
--- a/base/process/process_metrics_unittest.cc
+++ b/base/process/process_metrics_unittest.cc
@@ -12,11 +12,11 @@
 #include <string>
 #include <vector>
 
-#include "base/bind.h"
 #include "base/command_line.h"
 #include "base/files/file.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/functional/bind.h"
 #include "base/memory/shared_memory_mapping.h"
 #include "base/memory/writable_shared_memory_region.h"
 #include "base/ranges/algorithm.h"
diff --git a/base/process/process_util_unittest.cc b/base/process/process_util_unittest.cc
index 3e4792c..dfb9ed5 100644
--- a/base/process/process_util_unittest.cc
+++ b/base/process/process_util_unittest.cc
@@ -10,7 +10,6 @@
 #include <limits>
 #include <tuple>
 
-#include "base/bind.h"
 #include "base/command_line.h"
 #include "base/debug/alias.h"
 #include "base/debug/stack_trace.h"
@@ -18,6 +17,7 @@
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_file.h"
+#include "base/functional/bind.h"
 #include "base/logging.h"
 #include "base/path_service.h"
 #include "base/posix/eintr_wrapper.h"
diff --git a/base/profiler/libunwindstack_unwinder_android_unittest.cc b/base/profiler/libunwindstack_unwinder_android_unittest.cc
index 36291ac4..76eaeed 100644
--- a/base/profiler/libunwindstack_unwinder_android_unittest.cc
+++ b/base/profiler/libunwindstack_unwinder_android_unittest.cc
@@ -11,7 +11,7 @@
 #include <vector>
 
 #include "base/android/build_info.h"
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/profiler/register_context.h"
 #include "base/profiler/stack_buffer.h"
 #include "base/profiler/stack_copier_signal.h"
diff --git a/base/profiler/module_cache_unittest.cc b/base/profiler/module_cache_unittest.cc
index ea99ec6..fd4c9fa1 100644
--- a/base/profiler/module_cache_unittest.cc
+++ b/base/profiler/module_cache_unittest.cc
@@ -8,9 +8,9 @@
 #include <utility>
 #include <vector>
 
-#include "base/callback.h"
-#include "base/callback_helpers.h"
 #include "base/containers/adapters.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/profiler/module_cache.h"
 #include "base/ranges/algorithm.h"
 #include "base/strings/string_piece.h"
diff --git a/base/profiler/native_unwinder_android_unittest.cc b/base/profiler/native_unwinder_android_unittest.cc
index 06054e4..f96b9bd 100644
--- a/base/profiler/native_unwinder_android_unittest.cc
+++ b/base/profiler/native_unwinder_android_unittest.cc
@@ -15,7 +15,7 @@
 
 #include "base/android/build_info.h"
 #include "base/android/jni_android.h"
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/profiler/register_context.h"
 #include "base/profiler/stack_buffer.h"
 #include "base/profiler/stack_copier_signal.h"
diff --git a/base/profiler/stack_sampler.h b/base/profiler/stack_sampler.h
index b9a5ae81..9622453 100644
--- a/base/profiler/stack_sampler.h
+++ b/base/profiler/stack_sampler.h
@@ -9,8 +9,8 @@
 #include <vector>
 
 #include "base/base_export.h"
-#include "base/callback.h"
 #include "base/containers/circular_deque.h"
+#include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/profiler/frame.h"
 #include "base/profiler/register_context.h"
diff --git a/base/profiler/stack_sampler_ios.cc b/base/profiler/stack_sampler_ios.cc
index 4a67698..caacf56f 100644
--- a/base/profiler/stack_sampler_ios.cc
+++ b/base/profiler/stack_sampler_ios.cc
@@ -9,8 +9,8 @@
 #include "build/build_config.h"
 
 #if BUILDFLAG(IOS_STACK_PROFILER_ENABLED)
-#include "base/bind.h"
 #include "base/check.h"
+#include "base/functional/bind.h"
 #include "base/profiler/frame_pointer_unwinder.h"
 #include "base/profiler/stack_copier_suspend.h"
 #include "base/profiler/suspendable_thread_delegate_mac.h"
diff --git a/base/profiler/stack_sampler_mac.cc b/base/profiler/stack_sampler_mac.cc
index 686e680..a8620ba 100644
--- a/base/profiler/stack_sampler_mac.cc
+++ b/base/profiler/stack_sampler_mac.cc
@@ -6,8 +6,8 @@
 
 #include <memory>
 
-#include "base/bind.h"
 #include "base/check.h"
+#include "base/functional/bind.h"
 #include "base/memory/ptr_util.h"
 #include "base/profiler/frame_pointer_unwinder.h"
 #include "base/profiler/stack_copier_suspend.h"
diff --git a/base/profiler/stack_sampler_posix.cc b/base/profiler/stack_sampler_posix.cc
index 0d032b5..2df66ef 100644
--- a/base/profiler/stack_sampler_posix.cc
+++ b/base/profiler/stack_sampler_posix.cc
@@ -13,8 +13,8 @@
 #include "build/build_config.h"
 
 #if BUILDFLAG(IS_CHROMEOS) && defined(ARCH_CPU_X86_64)
-#include "base/bind.h"
 #include "base/check.h"
+#include "base/functional/bind.h"
 #include "base/profiler/frame_pointer_unwinder.h"
 #include "base/profiler/stack_copier_signal.h"
 #include "base/profiler/thread_delegate_posix.h"
diff --git a/base/profiler/stack_sampler_unittest.cc b/base/profiler/stack_sampler_unittest.cc
index 8b10555..41d593f 100644
--- a/base/profiler/stack_sampler_unittest.cc
+++ b/base/profiler/stack_sampler_unittest.cc
@@ -9,7 +9,7 @@
 #include <numeric>
 #include <utility>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/raw_ref.h"
diff --git a/base/profiler/stack_sampler_win.cc b/base/profiler/stack_sampler_win.cc
index 2d898c4..0519b6e 100644
--- a/base/profiler/stack_sampler_win.cc
+++ b/base/profiler/stack_sampler_win.cc
@@ -4,8 +4,8 @@
 
 #include "base/profiler/stack_sampler.h"
 
-#include "base/bind.h"
 #include "base/check.h"
+#include "base/functional/bind.h"
 #include "base/memory/ptr_util.h"
 #include "base/profiler/native_unwinder_win.h"
 #include "base/profiler/stack_copier_suspend.h"
diff --git a/base/profiler/stack_sampling_profiler.cc b/base/profiler/stack_sampling_profiler.cc
index 43d34f3..66e4280 100644
--- a/base/profiler/stack_sampling_profiler.cc
+++ b/base/profiler/stack_sampling_profiler.cc
@@ -11,9 +11,9 @@
 
 #include "base/atomic_sequence_num.h"
 #include "base/atomicops.h"
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/location.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
diff --git a/base/profiler/stack_sampling_profiler.h b/base/profiler/stack_sampling_profiler.h
index df9b426..0a98dba 100644
--- a/base/profiler/stack_sampling_profiler.h
+++ b/base/profiler/stack_sampling_profiler.h
@@ -9,7 +9,7 @@
 #include <vector>
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/profiler/profile_builder.h"
 #include "base/profiler/sampling_profiler_thread_token.h"
 #include "base/synchronization/waitable_event.h"
diff --git a/base/profiler/stack_sampling_profiler_test_util.cc b/base/profiler/stack_sampling_profiler_test_util.cc
index 453a5491..78730d2 100644
--- a/base/profiler/stack_sampling_profiler_test_util.cc
+++ b/base/profiler/stack_sampling_profiler_test_util.cc
@@ -7,8 +7,8 @@
 
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/location.h"
 #include "base/path_service.h"
 #include "base/profiler/profiler_buildflags.h"
diff --git a/base/profiler/stack_sampling_profiler_test_util.h b/base/profiler/stack_sampling_profiler_test_util.h
index 4a8d6c6..2148622 100644
--- a/base/profiler/stack_sampling_profiler_test_util.h
+++ b/base/profiler/stack_sampling_profiler_test_util.h
@@ -10,7 +10,7 @@
 #include <vector>
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/native_library.h"
 #include "base/profiler/frame.h"
diff --git a/base/profiler/stack_sampling_profiler_unittest.cc b/base/profiler/stack_sampling_profiler_unittest.cc
index 2663815..9d164fd 100644
--- a/base/profiler/stack_sampling_profiler_unittest.cc
+++ b/base/profiler/stack_sampling_profiler_unittest.cc
@@ -11,10 +11,10 @@
 #include <utility>
 #include <vector>
 
-#include "base/bind.h"
-#include "base/callback.h"
 #include "base/compiler_specific.h"
 #include "base/files/file_util.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/location.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
diff --git a/base/run_loop.cc b/base/run_loop.cc
index 83afb90..4ae85d5 100644
--- a/base/run_loop.cc
+++ b/base/run_loop.cc
@@ -4,10 +4,10 @@
 
 #include "base/run_loop.h"
 
-#include "base/bind.h"
-#include "base/callback.h"
 #include "base/cancelable_callback.h"
 #include "base/check.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/no_destructor.h"
 #include "base/observer_list.h"
 #include "base/task/single_thread_task_runner.h"
diff --git a/base/run_loop.h b/base/run_loop.h
index 2a7e8ae..1eff8509 100644
--- a/base/run_loop.h
+++ b/base/run_loop.h
@@ -10,9 +10,9 @@
 #include <vector>
 
 #include "base/base_export.h"
-#include "base/callback.h"
 #include "base/containers/stack.h"
 #include "base/dcheck_is_on.h"
+#include "base/functional/callback.h"
 #include "base/gtest_prod_util.h"
 #include "base/location.h"
 #include "base/memory/raw_ptr.h"
diff --git a/base/run_loop_unittest.cc b/base/run_loop_unittest.cc
index 93fd5fb..dc72d224 100644
--- a/base/run_loop_unittest.cc
+++ b/base/run_loop_unittest.cc
@@ -8,9 +8,9 @@
 #include <memory>
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/containers/queue.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/location.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.h"
diff --git a/base/sampling_heap_profiler/sampling_heap_profiler.cc b/base/sampling_heap_profiler/sampling_heap_profiler.cc
index 4acc2a3..8c7da26 100644
--- a/base/sampling_heap_profiler/sampling_heap_profiler.cc
+++ b/base/sampling_heap_profiler/sampling_heap_profiler.cc
@@ -10,10 +10,10 @@
 
 #include "base/allocator/partition_allocator/partition_alloc.h"
 #include "base/allocator/partition_allocator/shim/allocator_shim.h"
-#include "base/bind.h"
 #include "base/compiler_specific.h"
 #include "base/debug/stack_trace.h"
 #include "base/feature_list.h"
+#include "base/functional/bind.h"
 #include "base/logging.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/no_destructor.h"
diff --git a/base/sequence_checker_unittest.cc b/base/sequence_checker_unittest.cc
index 4b0142257..0141779 100644
--- a/base/sequence_checker_unittest.cc
+++ b/base/sequence_checker_unittest.cc
@@ -10,8 +10,8 @@
 #include <string>
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/sequence_token.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/task/thread_pool.h"
diff --git a/base/synchronization/atomic_flag_unittest.cc b/base/synchronization/atomic_flag_unittest.cc
index 65b82689..b7dc132a 100644
--- a/base/synchronization/atomic_flag_unittest.cc
+++ b/base/synchronization/atomic_flag_unittest.cc
@@ -4,8 +4,8 @@
 
 #include "base/synchronization/atomic_flag.h"
 
-#include "base/bind.h"
 #include "base/check_op.h"
+#include "base/functional/bind.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/test/gtest_util.h"
diff --git a/base/synchronization/condition_variable_unittest.cc b/base/synchronization/condition_variable_unittest.cc
index fe7a082..cc2587d 100644
--- a/base/synchronization/condition_variable_unittest.cc
+++ b/base/synchronization/condition_variable_unittest.cc
@@ -12,7 +12,7 @@
 #include <memory>
 #include <vector>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/synchronization/lock.h"
diff --git a/base/synchronization/waitable_event.h b/base/synchronization/waitable_event.h
index d84604e..514bba9 100644
--- a/base/synchronization/waitable_event.h
+++ b/base/synchronization/waitable_event.h
@@ -19,7 +19,7 @@
 #include <list>
 #include <memory>
 
-#include "base/callback_forward.h"
+#include "base/functional/callback_forward.h"
 #include "base/mac/scoped_mach_port.h"
 #include "base/memory/ref_counted.h"
 #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
diff --git a/base/synchronization/waitable_event_watcher.h b/base/synchronization/waitable_event_watcher.h
index da4b077..c69e35d0 100644
--- a/base/synchronization/waitable_event_watcher.h
+++ b/base/synchronization/waitable_event_watcher.h
@@ -25,7 +25,7 @@
 #endif
 
 #if !BUILDFLAG(IS_WIN)
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #endif
 
 namespace base {
diff --git a/base/synchronization/waitable_event_watcher_mac.cc b/base/synchronization/waitable_event_watcher_mac.cc
index f7a20f1..9c18429 100644
--- a/base/synchronization/waitable_event_watcher_mac.cc
+++ b/base/synchronization/waitable_event_watcher_mac.cc
@@ -4,8 +4,8 @@
 
 #include "base/synchronization/waitable_event_watcher.h"
 
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 
 namespace base {
 
diff --git a/base/synchronization/waitable_event_watcher_posix.cc b/base/synchronization/waitable_event_watcher_posix.cc
index b22f390..64f6518 100644
--- a/base/synchronization/waitable_event_watcher_posix.cc
+++ b/base/synchronization/waitable_event_watcher_posix.cc
@@ -6,8 +6,8 @@
 
 #include <utility>
 
-#include "base/bind.h"
 #include "base/check.h"
+#include "base/functional/bind.h"
 #include "base/synchronization/lock.h"
 #include "base/synchronization/waitable_event.h"
 
diff --git a/base/synchronization/waitable_event_watcher_unittest.cc b/base/synchronization/waitable_event_watcher_unittest.cc
index 17bc04a..1d85b72c 100644
--- a/base/synchronization/waitable_event_watcher_unittest.cc
+++ b/base/synchronization/waitable_event_watcher_unittest.cc
@@ -4,8 +4,8 @@
 
 #include "base/synchronization/waitable_event_watcher.h"
 
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
diff --git a/base/system/sys_info.cc b/base/system/sys_info.cc
index c4e96dd..2c5bfc9 100644
--- a/base/system/sys_info.cc
+++ b/base/system/sys_info.cc
@@ -7,9 +7,9 @@
 #include <algorithm>
 
 #include "base/base_switches.h"
-#include "base/bind.h"
-#include "base/callback.h"
 #include "base/command_line.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/location.h"
 #include "base/notreached.h"
 #include "base/system/sys_info_internal.h"
diff --git a/base/system/sys_info.h b/base/system/sys_info.h
index e7ad457..4a803a1 100644
--- a/base/system/sys_info.h
+++ b/base/system/sys_info.h
@@ -12,7 +12,7 @@
 #include <string>
 
 #include "base/base_export.h"
-#include "base/callback_forward.h"
+#include "base/functional/callback_forward.h"
 #include "base/gtest_prod_util.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
diff --git a/base/system/sys_info_unittest.cc b/base/system/sys_info_unittest.cc
index df2dca03..a0c96f7 100644
--- a/base/system/sys_info_unittest.cc
+++ b/base/system/sys_info_unittest.cc
@@ -7,9 +7,9 @@
 #include <utility>
 #include <vector>
 
-#include "base/bind.h"
 #include "base/environment.h"
 #include "base/files/file_util.h"
+#include "base/functional/bind.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/process/process_metrics.h"
 #include "base/run_loop.h"
diff --git a/base/task/bind_post_task.h b/base/task/bind_post_task.h
index bedf9f5..37b1c405 100644
--- a/base/task/bind_post_task.h
+++ b/base/task/bind_post_task.h
@@ -9,8 +9,8 @@
 #include <type_traits>
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/location.h"
 #include "base/task/bind_post_task_internal.h"
 #include "base/task/task_runner.h"
diff --git a/base/task/bind_post_task_internal.h b/base/task/bind_post_task_internal.h
index e2915eb..3e97f2f 100644
--- a/base/task/bind_post_task_internal.h
+++ b/base/task/bind_post_task_internal.h
@@ -7,9 +7,9 @@
 
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback.h"
 #include "base/check.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/location.h"
 #include "base/task/task_runner.h"
 #include "base/task/thread_pool/thread_pool_instance.h"
diff --git a/base/task/bind_post_task_unittest.cc b/base/task/bind_post_task_unittest.cc
index f09072ef..7bf7d29 100644
--- a/base/task/bind_post_task_unittest.cc
+++ b/base/task/bind_post_task_unittest.cc
@@ -4,8 +4,8 @@
 
 #include "base/task/bind_post_task.h"
 
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/memory/raw_ref.h"
 #include "base/sequence_checker_impl.h"
 #include "base/task/sequenced_task_runner.h"
diff --git a/base/task/bind_post_task_unittest.nc b/base/task/bind_post_task_unittest.nc
index 5aa1096..6cc2f88b 100644
--- a/base/task/bind_post_task_unittest.nc
+++ b/base/task/bind_post_task_unittest.nc
@@ -8,8 +8,8 @@
 #include "base/task/bind_post_task.h"
 
 #include "base/task/sequenced_task_runner.h"
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 
 namespace base {
 
diff --git a/base/task/cancelable_task_tracker.cc b/base/task/cancelable_task_tracker.cc
index 6b31f1a2..0acac41 100644
--- a/base/task/cancelable_task_tracker.cc
+++ b/base/task/cancelable_task_tracker.cc
@@ -8,9 +8,9 @@
 
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/feature_list.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/location.h"
 #include "base/memory/ref_counted.h"
 #include "base/metrics/histogram_macros.h"
diff --git a/base/task/cancelable_task_tracker.h b/base/task/cancelable_task_tracker.h
index 1010b2a..250c274 100644
--- a/base/task/cancelable_task_tracker.h
+++ b/base/task/cancelable_task_tracker.h
@@ -42,10 +42,10 @@
 #include <utility>
 
 #include "base/base_export.h"
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
 #include "base/containers/small_map.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "base/sequence_checker.h"
diff --git a/base/task/cancelable_task_tracker_unittest.cc b/base/task/cancelable_task_tracker_unittest.cc
index 3c163b3..2f84bdc 100644
--- a/base/task/cancelable_task_tracker_unittest.cc
+++ b/base/task/cancelable_task_tracker_unittest.cc
@@ -7,9 +7,9 @@
 #include <cstddef>
 #include <tuple>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/check_op.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/location.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
diff --git a/base/task/common/task_annotator_unittest.cc b/base/task/common/task_annotator_unittest.cc
index 5c71c39..e071ba0 100644
--- a/base/task/common/task_annotator_unittest.cc
+++ b/base/task/common/task_annotator_unittest.cc
@@ -7,9 +7,9 @@
 #include <algorithm>
 #include <vector>
 
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/pending_task.h"
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
diff --git a/base/task/current_thread.cc b/base/task/current_thread.cc
index 89e1232..05daff86 100644
--- a/base/task/current_thread.cc
+++ b/base/task/current_thread.cc
@@ -4,8 +4,8 @@
 
 #include "base/task/current_thread.h"
 
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/message_loop/message_pump_for_io.h"
 #include "base/message_loop/message_pump_for_ui.h"
 #include "base/message_loop/message_pump_type.h"
diff --git a/base/task/current_thread.h b/base/task/current_thread.h
index 9eb954fc..6e5aea5 100644
--- a/base/task/current_thread.h
+++ b/base/task/current_thread.h
@@ -8,8 +8,8 @@
 #include <ostream>
 
 #include "base/base_export.h"
-#include "base/callback_forward.h"
 #include "base/check.h"
+#include "base/functional/callback_forward.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/message_loop/message_pump_for_io.h"
diff --git a/base/task/default_delayed_task_handle_delegate.cc b/base/task/default_delayed_task_handle_delegate.cc
index df6846d..28dd357 100644
--- a/base/task/default_delayed_task_handle_delegate.cc
+++ b/base/task/default_delayed_task_handle_delegate.cc
@@ -6,7 +6,7 @@
 
 #include <utility>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 
 namespace base {
 
diff --git a/base/task/default_delayed_task_handle_delegate.h b/base/task/default_delayed_task_handle_delegate.h
index d27a97f..beaf828 100644
--- a/base/task/default_delayed_task_handle_delegate.h
+++ b/base/task/default_delayed_task_handle_delegate.h
@@ -6,7 +6,7 @@
 #define BASE_TASK_DEFAULT_DELAYED_TASK_HANDLE_DELEGATE_H_
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/memory/weak_ptr.h"
 #include "base/task/delayed_task_handle.h"
 
diff --git a/base/task/default_delayed_task_handle_delegate_unittest.cc b/base/task/default_delayed_task_handle_delegate_unittest.cc
index 7b92ddb..0017c7ff 100644
--- a/base/task/default_delayed_task_handle_delegate_unittest.cc
+++ b/base/task/default_delayed_task_handle_delegate_unittest.cc
@@ -4,7 +4,7 @@
 
 #include "base/task/default_delayed_task_handle_delegate.h"
 
-#include "base/callback_helpers.h"
+#include "base/functional/callback_helpers.h"
 #include "base/task/delayed_task_handle.h"
 #include "base/test/bind.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/task/deferred_sequenced_task_runner.cc b/base/task/deferred_sequenced_task_runner.cc
index 4e9fbd29..f712b61 100644
--- a/base/task/deferred_sequenced_task_runner.cc
+++ b/base/task/deferred_sequenced_task_runner.cc
@@ -7,8 +7,8 @@
 
 #include <utility>
 
-#include "base/bind.h"
 #include "base/check.h"
+#include "base/functional/bind.h"
 
 namespace base {
 
diff --git a/base/task/deferred_sequenced_task_runner.h b/base/task/deferred_sequenced_task_runner.h
index c85a4e5..d1b4ac76 100644
--- a/base/task/deferred_sequenced_task_runner.h
+++ b/base/task/deferred_sequenced_task_runner.h
@@ -8,8 +8,8 @@
 #include <vector>
 
 #include "base/base_export.h"
-#include "base/callback.h"
 #include "base/compiler_specific.h"
+#include "base/functional/callback.h"
 #include "base/synchronization/lock.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/threading/platform_thread.h"
diff --git a/base/task/deferred_sequenced_task_runner_unittest.cc b/base/task/deferred_sequenced_task_runner_unittest.cc
index 7616b51..9360c0de 100644
--- a/base/task/deferred_sequenced_task_runner_unittest.cc
+++ b/base/task/deferred_sequenced_task_runner_unittest.cc
@@ -4,8 +4,8 @@
 
 #include "base/task/deferred_sequenced_task_runner.h"
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/location.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
diff --git a/base/task/job_perftest.cc b/base/task/job_perftest.cc
index d309abd..1368516 100644
--- a/base/task/job_perftest.cc
+++ b/base/task/job_perftest.cc
@@ -7,9 +7,9 @@
 #include <utility>
 #include <vector>
 
-#include "base/callback_helpers.h"
 #include "base/containers/queue.h"
 #include "base/containers/stack.h"
+#include "base/functional/callback_helpers.h"
 #include "base/synchronization/lock.h"
 #include "base/task/post_job.h"
 #include "base/task/thread_pool.h"
diff --git a/base/task/lazy_thread_pool_task_runner.h b/base/task/lazy_thread_pool_task_runner.h
index 424f96c..34d0de8 100644
--- a/base/task/lazy_thread_pool_task_runner.h
+++ b/base/task/lazy_thread_pool_task_runner.h
@@ -9,7 +9,7 @@
 #include <vector>
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/task/common/checked_lock.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/task/single_thread_task_runner.h"
diff --git a/base/task/lazy_thread_pool_task_runner_unittest.cc b/base/task/lazy_thread_pool_task_runner_unittest.cc
index 897eacb7..e1a17a2 100644
--- a/base/task/lazy_thread_pool_task_runner_unittest.cc
+++ b/base/task/lazy_thread_pool_task_runner_unittest.cc
@@ -4,8 +4,8 @@
 
 #include "base/task/lazy_thread_pool_task_runner.h"
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/sequence_checker_impl.h"
 #include "base/task/scoped_set_task_priority_for_current_thread.h"
 #include "base/test/task_environment.h"
diff --git a/base/task/post_job.h b/base/task/post_job.h
index ff2a221..582aa61 100644
--- a/base/task/post_job.h
+++ b/base/task/post_job.h
@@ -8,8 +8,8 @@
 #include <limits>
 
 #include "base/base_export.h"
-#include "base/callback.h"
 #include "base/dcheck_is_on.h"
+#include "base/functional/callback.h"
 #include "base/location.h"
 #include "base/memory/raw_ptr.h"
 
diff --git a/base/task/post_task_and_reply_with_result_internal.h b/base/task/post_task_and_reply_with_result_internal.h
index 6e4f4464..053ff77 100644
--- a/base/task/post_task_and_reply_with_result_internal.h
+++ b/base/task/post_task_and_reply_with_result_internal.h
@@ -8,8 +8,8 @@
 #include <memory>
 #include <utility>
 
-#include "base/callback.h"
 #include "base/check.h"
+#include "base/functional/callback.h"
 
 namespace base {
 
diff --git a/base/task/sequence_manager/atomic_flag_set.cc b/base/task/sequence_manager/atomic_flag_set.cc
index d8322eb..34605009 100644
--- a/base/task/sequence_manager/atomic_flag_set.cc
+++ b/base/task/sequence_manager/atomic_flag_set.cc
@@ -7,8 +7,8 @@
 #include <utility>
 
 #include "base/bits.h"
-#include "base/callback.h"
 #include "base/check_op.h"
+#include "base/functional/callback.h"
 
 namespace base {
 namespace sequence_manager {
diff --git a/base/task/sequence_manager/atomic_flag_set.h b/base/task/sequence_manager/atomic_flag_set.h
index c6f52ca7..e3c7d06 100644
--- a/base/task/sequence_manager/atomic_flag_set.h
+++ b/base/task/sequence_manager/atomic_flag_set.h
@@ -9,7 +9,7 @@
 #include <memory>
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/task/sequence_manager/associated_thread_id.h"
 
diff --git a/base/task/sequence_manager/sequence_manager_impl.cc b/base/task/sequence_manager/sequence_manager_impl.cc
index 321c609..4563065 100644
--- a/base/task/sequence_manager/sequence_manager_impl.cc
+++ b/base/task/sequence_manager/sequence_manager_impl.cc
@@ -8,12 +8,12 @@
 #include <queue>
 #include <vector>
 
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
 #include "base/compiler_specific.h"
 #include "base/debug/crash_logging.h"
 #include "base/debug/stack_trace.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/json/json_writer.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
diff --git a/base/task/sequence_manager/sequence_manager_impl.h b/base/task/sequence_manager/sequence_manager_impl.h
index 19c8fd6..8ac3dd7 100644
--- a/base/task/sequence_manager/sequence_manager_impl.h
+++ b/base/task/sequence_manager/sequence_manager_impl.h
@@ -14,11 +14,11 @@
 
 #include "base/atomic_sequence_num.h"
 #include "base/base_export.h"
-#include "base/callback_forward.h"
 #include "base/cancelable_callback.h"
 #include "base/containers/circular_deque.h"
 #include "base/debug/crash_logging.h"
 #include "base/feature_list.h"
+#include "base/functional/callback_forward.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
diff --git a/base/task/sequence_manager/sequence_manager_impl_unittest.cc b/base/task/sequence_manager/sequence_manager_impl_unittest.cc
index 3905f9d4b..3d857b1 100644
--- a/base/task/sequence_manager/sequence_manager_impl_unittest.cc
+++ b/base/task/sequence_manager/sequence_manager_impl_unittest.cc
@@ -12,11 +12,11 @@
 #include <vector>
 
 #include "base/auto_reset.h"
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_forward.h"
-#include "base/callback_helpers.h"
 #include "base/cancelable_callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_forward.h"
+#include "base/functional/callback_helpers.h"
 #include "base/location.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted_memory.h"
diff --git a/base/task/sequence_manager/sequence_manager_perftest.cc b/base/task/sequence_manager/sequence_manager_perftest.cc
index f8da3be..af5369c 100644
--- a/base/task/sequence_manager/sequence_manager_perftest.cc
+++ b/base/task/sequence_manager/sequence_manager_perftest.cc
@@ -8,7 +8,7 @@
 #include <stddef.h>
 #include <memory>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/logging.h"
 #include "base/message_loop/message_pump_default.h"
 #include "base/message_loop/message_pump_type.h"
diff --git a/base/task/sequence_manager/sequenced_task_source.h b/base/task/sequence_manager/sequenced_task_source.h
index 0b33f7a..da2d273 100644
--- a/base/task/sequence_manager/sequenced_task_source.h
+++ b/base/task/sequence_manager/sequenced_task_source.h
@@ -6,7 +6,7 @@
 #define BASE_TASK_SEQUENCE_MANAGER_SEQUENCED_TASK_SOURCE_H_
 
 #include "base/base_export.h"
-#include "base/callback_helpers.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/raw_ref.h"
 #include "base/pending_task.h"
 #include "base/task/common/lazy_now.h"
diff --git a/base/task/sequence_manager/task_queue.cc b/base/task/sequence_manager/task_queue.cc
index df00478e..2260bef 100644
--- a/base/task/sequence_manager/task_queue.cc
+++ b/base/task/sequence_manager/task_queue.cc
@@ -6,7 +6,7 @@
 
 #include <utility>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/memory/ptr_util.h"
 #include "base/task/sequence_manager/associated_thread_id.h"
 #include "base/task/sequence_manager/sequence_manager_impl.h"
diff --git a/base/task/sequence_manager/task_queue_impl.h b/base/task/sequence_manager/task_queue_impl.h
index c763a2f..57ec8ad 100644
--- a/base/task/sequence_manager/task_queue_impl.h
+++ b/base/task/sequence_manager/task_queue_impl.h
@@ -15,10 +15,10 @@
 #include <vector>
 
 #include "base/base_export.h"
-#include "base/callback.h"
 #include "base/containers/flat_map.h"
 #include "base/containers/intrusive_heap.h"
 #include "base/dcheck_is_on.h"
+#include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
diff --git a/base/task/sequence_manager/task_queue_selector_unittest.cc b/base/task/sequence_manager/task_queue_selector_unittest.cc
index 7adaba44..b0a198b9 100644
--- a/base/task/sequence_manager/task_queue_selector_unittest.cc
+++ b/base/task/sequence_manager/task_queue_selector_unittest.cc
@@ -12,7 +12,7 @@
 #include <utility>
 #include <vector>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/memory/ptr_util.h"
 #include "base/pending_task.h"
 #include "base/task/sequence_manager/enqueue_order_generator.h"
diff --git a/base/task/sequence_manager/test/mock_time_message_pump.h b/base/task/sequence_manager/test/mock_time_message_pump.h
index 36752e0..6fca818 100644
--- a/base/task/sequence_manager/test/mock_time_message_pump.h
+++ b/base/task/sequence_manager/test/mock_time_message_pump.h
@@ -5,7 +5,7 @@
 #ifndef BASE_TASK_SEQUENCE_MANAGER_TEST_MOCK_TIME_MESSAGE_PUMP_H_
 #define BASE_TASK_SEQUENCE_MANAGER_TEST_MOCK_TIME_MESSAGE_PUMP_H_
 
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/message_loop/message_pump.h"
 #include "base/synchronization/waitable_event.h"
diff --git a/base/task/sequence_manager/thread_controller_impl.cc b/base/task/sequence_manager/thread_controller_impl.cc
index 91f3b523..d5564e2 100644
--- a/base/task/sequence_manager/thread_controller_impl.cc
+++ b/base/task/sequence_manager/thread_controller_impl.cc
@@ -6,7 +6,7 @@
 
 #include <algorithm>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/memory/ptr_util.h"
 #include "base/message_loop/message_pump.h"
 #include "base/notreached.h"
diff --git a/base/task/sequence_manager/thread_controller_with_message_pump_impl_unittest.cc b/base/task/sequence_manager/thread_controller_with_message_pump_impl_unittest.cc
index 5533ce3..a3d8a47 100644
--- a/base/task/sequence_manager/thread_controller_with_message_pump_impl_unittest.cc
+++ b/base/task/sequence_manager/thread_controller_with_message_pump_impl_unittest.cc
@@ -8,9 +8,9 @@
 #include <string>
 #include <utility>
 #include <vector>
-#include "base/bind.h"
-#include "base/callback_forward.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_forward.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/task/sequence_manager/task_queue.h"
diff --git a/base/task/sequence_manager/work_queue_sets_unittest.cc b/base/task/sequence_manager/work_queue_sets_unittest.cc
index 1031086..0b2e272 100644
--- a/base/task/sequence_manager/work_queue_sets_unittest.cc
+++ b/base/task/sequence_manager/work_queue_sets_unittest.cc
@@ -8,7 +8,7 @@
 
 #include <memory>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/memory/ptr_util.h"
 #include "base/task/sequence_manager/enqueue_order.h"
 #include "base/task/sequence_manager/fence.h"
diff --git a/base/task/sequence_manager/work_queue_unittest.cc b/base/task/sequence_manager/work_queue_unittest.cc
index 2c5291f..b606834 100644
--- a/base/task/sequence_manager/work_queue_unittest.cc
+++ b/base/task/sequence_manager/work_queue_unittest.cc
@@ -7,7 +7,7 @@
 #include <stddef.h>
 #include <memory>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/task/common/lazy_now.h"
 #include "base/task/sequence_manager/enqueue_order.h"
 #include "base/task/sequence_manager/fence.h"
diff --git a/base/task/sequenced_task_runner.cc b/base/task/sequenced_task_runner.cc
index c132346..7efadd3 100644
--- a/base/task/sequenced_task_runner.cc
+++ b/base/task/sequenced_task_runner.cc
@@ -6,7 +6,7 @@
 
 #include <utility>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/no_destructor.h"
 #include "base/task/default_delayed_task_handle_delegate.h"
 #include "base/threading/thread_local.h"
diff --git a/base/task/sequenced_task_runner.h b/base/task/sequenced_task_runner.h
index 16ae0287..669f36a0 100644
--- a/base/task/sequenced_task_runner.h
+++ b/base/task/sequenced_task_runner.h
@@ -8,7 +8,7 @@
 #include <memory>
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/task/delay_policy.h"
 #include "base/task/delayed_task_handle.h"
 #include "base/task/sequenced_task_runner_helpers.h"
diff --git a/base/task/sequenced_task_runner_unittest.cc b/base/task/sequenced_task_runner_unittest.cc
index c4fd0d8c..465b25e 100644
--- a/base/task/sequenced_task_runner_unittest.cc
+++ b/base/task/sequenced_task_runner_unittest.cc
@@ -6,9 +6,9 @@
 
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/gtest_prod_util.h"
 #include "base/location.h"
 #include "base/memory/raw_ptr.h"
diff --git a/base/task/single_thread_task_executor_unittest.cc b/base/task/single_thread_task_executor_unittest.cc
index ba694e8..0193713 100644
--- a/base/task/single_thread_task_executor_unittest.cc
+++ b/base/task/single_thread_task_executor_unittest.cc
@@ -10,9 +10,9 @@
 #include <string>
 #include <vector>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/compiler_specific.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
diff --git a/base/task/single_thread_task_runner.cc b/base/task/single_thread_task_runner.cc
index cee10d0b..ebf28671 100644
--- a/base/task/single_thread_task_runner.cc
+++ b/base/task/single_thread_task_runner.cc
@@ -7,10 +7,10 @@
 #include <memory>
 #include <utility>
 
-#include "base/bind.h"
 #include "base/check.h"
 #include "base/check_op.h"
 #include "base/dcheck_is_on.h"
+#include "base/functional/bind.h"
 #include "base/lazy_instance.h"
 #include "base/no_destructor.h"
 #include "base/run_loop.h"
diff --git a/base/task/task_runner.cc b/base/task/task_runner.cc
index 2b77db6..1ed7307 100644
--- a/base/task/task_runner.cc
+++ b/base/task/task_runner.cc
@@ -6,9 +6,9 @@
 
 #include <utility>
 
-#include "base/bind.h"
 #include "base/check.h"
 #include "base/compiler_specific.h"
+#include "base/functional/bind.h"
 #include "base/memory/raw_ptr.h"
 #include "base/threading/post_task_and_reply_impl.h"
 #include "base/time/time.h"
diff --git a/base/task/task_runner.h b/base/task/task_runner.h
index 6bb373f..287fc748 100644
--- a/base/task/task_runner.h
+++ b/base/task/task_runner.h
@@ -8,10 +8,10 @@
 #include <stddef.h>
 
 #include "base/base_export.h"
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
 #include "base/check.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/location.h"
 #include "base/memory/ref_counted.h"
 #include "base/task/post_task_and_reply_with_result_internal.h"
diff --git a/base/task/task_runner_unittest.cc b/base/task/task_runner_unittest.cc
index d844046..7091a4b 100644
--- a/base/task/task_runner_unittest.cc
+++ b/base/task/task_runner_unittest.cc
@@ -7,7 +7,7 @@
 #include <memory>
 #include <utility>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/location.h"
 #include "base/run_loop.h"
 #include "base/task/single_thread_task_runner.h"
diff --git a/base/task/thread_pool.h b/base/task/thread_pool.h
index 02e1b86..bc7ba0b 100644
--- a/base/task/thread_pool.h
+++ b/base/task/thread_pool.h
@@ -9,9 +9,9 @@
 #include <utility>
 
 #include "base/base_export.h"
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/location.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/task/post_task_and_reply_with_result_internal.h"
diff --git a/base/task/thread_pool/delayed_priority_queue_unittest.cc b/base/task/thread_pool/delayed_priority_queue_unittest.cc
index 1543479..4300988 100644
--- a/base/task/thread_pool/delayed_priority_queue_unittest.cc
+++ b/base/task/thread_pool/delayed_priority_queue_unittest.cc
@@ -7,7 +7,7 @@
 #include <memory>
 #include <utility>
 
-#include "base/callback_helpers.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/task/task_traits.h"
diff --git a/base/task/thread_pool/delayed_task_manager.cc b/base/task/thread_pool/delayed_task_manager.cc
index fdc391d..4b61aa6 100644
--- a/base/task/thread_pool/delayed_task_manager.cc
+++ b/base/task/thread_pool/delayed_task_manager.cc
@@ -6,9 +6,9 @@
 
 #include <algorithm>
 
-#include "base/bind.h"
 #include "base/check.h"
 #include "base/feature_list.h"
+#include "base/functional/bind.h"
 #include "base/task/common/checked_lock.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/task/task_features.h"
diff --git a/base/task/thread_pool/delayed_task_manager.h b/base/task/thread_pool/delayed_task_manager.h
index a04b4e3..b055a50 100644
--- a/base/task/thread_pool/delayed_task_manager.h
+++ b/base/task/thread_pool/delayed_task_manager.h
@@ -8,8 +8,8 @@
 #include <functional>
 
 #include "base/base_export.h"
-#include "base/callback.h"
 #include "base/containers/intrusive_heap.h"
+#include "base/functional/callback.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/synchronization/atomic_flag.h"
diff --git a/base/task/thread_pool/delayed_task_manager_unittest.cc b/base/task/thread_pool/delayed_task_manager_unittest.cc
index c9c0dd5..70f5fe85 100644
--- a/base/task/thread_pool/delayed_task_manager_unittest.cc
+++ b/base/task/thread_pool/delayed_task_manager_unittest.cc
@@ -7,9 +7,9 @@
 #include <memory>
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/cancelable_callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/synchronization/waitable_event.h"
diff --git a/base/task/thread_pool/job_task_source.cc b/base/task/thread_pool/job_task_source.cc
index de92c80..529f53c 100644
--- a/base/task/thread_pool/job_task_source.cc
+++ b/base/task/thread_pool/job_task_source.cc
@@ -7,10 +7,10 @@
 #include <type_traits>
 #include <utility>
 
-#include "base/bind.h"
 #include "base/bits.h"
-#include "base/callback_helpers.h"
 #include "base/check_op.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/ptr_util.h"
 #include "base/notreached.h"
 #include "base/task/common/checked_lock.h"
diff --git a/base/task/thread_pool/job_task_source.h b/base/task/thread_pool/job_task_source.h
index 5c43127..71d902a 100644
--- a/base/task/thread_pool/job_task_source.h
+++ b/base/task/thread_pool/job_task_source.h
@@ -13,7 +13,7 @@
 #include <utility>
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/synchronization/condition_variable.h"
 #include "base/task/common/checked_lock.h"
diff --git a/base/task/thread_pool/job_task_source_unittest.cc b/base/task/thread_pool/job_task_source_unittest.cc
index 4ff3f69..82a23e4 100644
--- a/base/task/thread_pool/job_task_source_unittest.cc
+++ b/base/task/thread_pool/job_task_source_unittest.cc
@@ -6,7 +6,7 @@
 
 #include <utility>
 
-#include "base/callback_helpers.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/ptr_util.h"
 #include "base/task/thread_pool/pooled_task_runner_delegate.h"
 #include "base/task/thread_pool/test_utils.h"
diff --git a/base/task/thread_pool/pooled_parallel_task_runner.h b/base/task/thread_pool/pooled_parallel_task_runner.h
index d2a3745..030f742 100644
--- a/base/task/thread_pool/pooled_parallel_task_runner.h
+++ b/base/task/thread_pool/pooled_parallel_task_runner.h
@@ -6,7 +6,7 @@
 #define BASE_TASK_THREAD_POOL_POOLED_PARALLEL_TASK_RUNNER_H_
 
 #include "base/base_export.h"
-#include "base/callback_forward.h"
+#include "base/functional/callback_forward.h"
 #include "base/location.h"
 #include "base/memory/raw_ptr.h"
 #include "base/task/task_runner.h"
diff --git a/base/task/thread_pool/pooled_sequenced_task_runner.h b/base/task/thread_pool/pooled_sequenced_task_runner.h
index 5d5a3fe..9f7fbdc 100644
--- a/base/task/thread_pool/pooled_sequenced_task_runner.h
+++ b/base/task/thread_pool/pooled_sequenced_task_runner.h
@@ -6,7 +6,7 @@
 #define BASE_TASK_THREAD_POOL_POOLED_SEQUENCED_TASK_RUNNER_H_
 
 #include "base/base_export.h"
-#include "base/callback_forward.h"
+#include "base/functional/callback_forward.h"
 #include "base/location.h"
 #include "base/memory/raw_ptr.h"
 #include "base/task/task_traits.h"
diff --git a/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc b/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc
index 6585aff..2693e060 100644
--- a/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc
+++ b/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc
@@ -8,9 +8,9 @@
 #include <string>
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback.h"
 #include "base/debug/leak_annotations.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/ranges/algorithm.h"
diff --git a/base/task/thread_pool/pooled_single_thread_task_runner_manager_unittest.cc b/base/task/thread_pool/pooled_single_thread_task_runner_manager_unittest.cc
index 136ea27..bd98250 100644
--- a/base/task/thread_pool/pooled_single_thread_task_runner_manager_unittest.cc
+++ b/base/task/thread_pool/pooled_single_thread_task_runner_manager_unittest.cc
@@ -4,8 +4,8 @@
 
 #include "base/task/thread_pool/pooled_single_thread_task_runner_manager.h"
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/synchronization/atomic_flag.h"
diff --git a/base/task/thread_pool/priority_queue_unittest.cc b/base/task/thread_pool/priority_queue_unittest.cc
index 46d4618..a42ee1e8 100644
--- a/base/task/thread_pool/priority_queue_unittest.cc
+++ b/base/task/thread_pool/priority_queue_unittest.cc
@@ -7,7 +7,7 @@
 #include <memory>
 #include <utility>
 
-#include "base/callback_helpers.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/task/task_traits.h"
diff --git a/base/task/thread_pool/sequence.cc b/base/task/thread_pool/sequence.cc
index 666a2c6..b82760e 100644
--- a/base/task/thread_pool/sequence.cc
+++ b/base/task/thread_pool/sequence.cc
@@ -6,10 +6,10 @@
 
 #include <utility>
 
-#include "base/bind.h"
 #include "base/check.h"
 #include "base/critical_closure.h"
 #include "base/feature_list.h"
+#include "base/functional/bind.h"
 #include "base/memory/ptr_util.h"
 #include "base/task/task_features.h"
 #include "base/time/time.h"
diff --git a/base/task/thread_pool/sequence_unittest.cc b/base/task/thread_pool/sequence_unittest.cc
index 2588415d..84a7bf1 100644
--- a/base/task/thread_pool/sequence_unittest.cc
+++ b/base/task/thread_pool/sequence_unittest.cc
@@ -6,8 +6,8 @@
 
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/ptr_util.h"
 #include "base/test/gtest_util.h"
 #include "base/time/time.h"
diff --git a/base/task/thread_pool/service_thread_unittest.cc b/base/task/thread_pool/service_thread_unittest.cc
index 4e16b0a2..9a7e796 100644
--- a/base/task/thread_pool/service_thread_unittest.cc
+++ b/base/task/thread_pool/service_thread_unittest.cc
@@ -6,8 +6,8 @@
 
 #include <string>
 
-#include "base/bind.h"
 #include "base/debug/stack_trace.h"
+#include "base/functional/bind.h"
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/base/task/thread_pool/task.h b/base/task/thread_pool/task.h
index 4e89eea..2af88aa 100644
--- a/base/task/thread_pool/task.h
+++ b/base/task/thread_pool/task.h
@@ -6,8 +6,8 @@
 #define BASE_TASK_THREAD_POOL_TASK_H_
 
 #include "base/base_export.h"
-#include "base/callback.h"
 #include "base/containers/intrusive_heap.h"
+#include "base/functional/callback.h"
 #include "base/location.h"
 #include "base/pending_task.h"
 #include "base/task/sequenced_task_runner.h"
diff --git a/base/task/thread_pool/task_tracker.cc b/base/task/thread_pool/task_tracker.cc
index 66565b0..51f2e15 100644
--- a/base/task/thread_pool/task_tracker.cc
+++ b/base/task/thread_pool/task_tracker.cc
@@ -9,10 +9,10 @@
 #include <utility>
 
 #include "base/base_switches.h"
-#include "base/callback.h"
 #include "base/command_line.h"
 #include "base/compiler_specific.h"
 #include "base/debug/alias.h"
+#include "base/functional/callback.h"
 #include "base/json/json_writer.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
diff --git a/base/task/thread_pool/task_tracker.h b/base/task/thread_pool/task_tracker.h
index 508ac6e..2a25c36f 100644
--- a/base/task/thread_pool/task_tracker.h
+++ b/base/task/thread_pool/task_tracker.h
@@ -14,8 +14,8 @@
 
 #include "base/atomicops.h"
 #include "base/base_export.h"
-#include "base/callback_forward.h"
 #include "base/containers/circular_deque.h"
+#include "base/functional/callback_forward.h"
 #include "base/sequence_checker.h"
 #include "base/strings/string_piece.h"
 #include "base/synchronization/waitable_event.h"
diff --git a/base/task/thread_pool/task_tracker_unittest.cc b/base/task/thread_pool/task_tracker_unittest.cc
index 61f180ac..b89082a0 100644
--- a/base/task/thread_pool/task_tracker_unittest.cc
+++ b/base/task/thread_pool/task_tracker_unittest.cc
@@ -11,10 +11,10 @@
 #include <vector>
 
 #include "base/barrier_closure.h"
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
 #include "base/check_op.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
diff --git a/base/task/thread_pool/test_task_factory.cc b/base/task/thread_pool/test_task_factory.cc
index f6f2176a..a9d9fa99 100644
--- a/base/task/thread_pool/test_task_factory.cc
+++ b/base/task/thread_pool/test_task_factory.cc
@@ -4,10 +4,10 @@
 
 #include "base/task/thread_pool/test_task_factory.h"
 
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
 #include "base/check_op.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/location.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/task/sequenced_task_runner.h"
diff --git a/base/task/thread_pool/test_task_factory.h b/base/task/thread_pool/test_task_factory.h
index d69c05ea..9805eb3c 100644
--- a/base/task/thread_pool/test_task_factory.h
+++ b/base/task/thread_pool/test_task_factory.h
@@ -9,7 +9,7 @@
 
 #include <unordered_set>
 
-#include "base/callback_forward.h"
+#include "base/functional/callback_forward.h"
 #include "base/memory/ref_counted.h"
 #include "base/synchronization/condition_variable.h"
 #include "base/synchronization/lock.h"
diff --git a/base/task/thread_pool/test_utils.cc b/base/task/thread_pool/test_utils.cc
index 63f8ea2..880b419 100644
--- a/base/task/thread_pool/test_utils.cc
+++ b/base/task/thread_pool/test_utils.cc
@@ -6,8 +6,8 @@
 
 #include <utility>
 
-#include "base/bind.h"
 #include "base/debug/leak_annotations.h"
+#include "base/functional/bind.h"
 #include "base/memory/raw_ptr.h"
 #include "base/synchronization/condition_variable.h"
 #include "base/task/thread_pool/pooled_parallel_task_runner.h"
diff --git a/base/task/thread_pool/test_utils.h b/base/task/thread_pool/test_utils.h
index e7a43db..1db33ff 100644
--- a/base/task/thread_pool/test_utils.h
+++ b/base/task/thread_pool/test_utils.h
@@ -8,7 +8,7 @@
 #include <atomic>
 #include <memory>
 
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/task/common/checked_lock.h"
 #include "base/task/post_job.h"
diff --git a/base/task/thread_pool/thread_group.cc b/base/task/thread_pool/thread_group.cc
index 5d9a5e0..8eb2e95 100644
--- a/base/task/thread_pool/thread_group.cc
+++ b/base/task/thread_pool/thread_group.cc
@@ -6,9 +6,9 @@
 
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/feature_list.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/lazy_instance.h"
 #include "base/task/task_features.h"
 #include "base/task/thread_pool/task_tracker.h"
diff --git a/base/task/thread_pool/thread_group_impl.cc b/base/task/thread_pool/thread_group_impl.cc
index 32036d4..5329e5d 100644
--- a/base/task/thread_pool/thread_group_impl.cc
+++ b/base/task/thread_pool/thread_group_impl.cc
@@ -12,11 +12,11 @@
 
 #include "base/atomicops.h"
 #include "base/auto_reset.h"
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/compiler_specific.h"
 #include "base/containers/stack_container.h"
 #include "base/feature_list.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/location.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
diff --git a/base/task/thread_pool/thread_group_impl_unittest.cc b/base/task/thread_pool/thread_group_impl_unittest.cc
index e28c79e..3bbc5c9 100644
--- a/base/task/thread_pool/thread_group_impl_unittest.cc
+++ b/base/task/thread_pool/thread_group_impl_unittest.cc
@@ -15,9 +15,9 @@
 
 #include "base/atomicops.h"
 #include "base/barrier_closure.h"
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
diff --git a/base/task/thread_pool/thread_group_unittest.cc b/base/task/thread_pool/thread_group_unittest.cc
index 233c84b..a487feb 100644
--- a/base/task/thread_pool/thread_group_unittest.cc
+++ b/base/task/thread_pool/thread_group_unittest.cc
@@ -9,8 +9,8 @@
 #include <utility>
 
 #include "base/barrier_closure.h"
-#include "base/bind.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/location.h"
 #include "base/memory/ref_counted.h"
 #include "base/task/task_runner.h"
diff --git a/base/task/thread_pool/thread_pool_impl.cc b/base/task/thread_pool/thread_pool_impl.cc
index d6177c8..d8595fd8 100644
--- a/base/task/thread_pool/thread_pool_impl.cc
+++ b/base/task/thread_pool/thread_pool_impl.cc
@@ -9,13 +9,13 @@
 #include <utility>
 
 #include "base/base_switches.h"
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/command_line.h"
 #include "base/compiler_specific.h"
 #include "base/debug/alias.h"
 #include "base/debug/leak_annotations.h"
 #include "base/feature_list.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/message_loop/message_pump_type.h"
 #include "base/metrics/field_trial_params.h"
 #include "base/strings/string_util.h"
diff --git a/base/task/thread_pool/thread_pool_impl.h b/base/task/thread_pool/thread_pool_impl.h
index ebc0833a..633c3e7d 100644
--- a/base/task/thread_pool/thread_pool_impl.h
+++ b/base/task/thread_pool/thread_pool_impl.h
@@ -8,8 +8,8 @@
 #include <memory>
 
 #include "base/base_export.h"
-#include "base/callback.h"
 #include "base/dcheck_is_on.h"
+#include "base/functional/callback.h"
 #include "base/memory/ptr_util.h"
 #include "base/sequence_checker.h"
 #include "base/strings/string_piece.h"
diff --git a/base/task/thread_pool/thread_pool_impl_unittest.cc b/base/task/thread_pool/thread_pool_impl_unittest.cc
index 0f882b3..a4d1d8be 100644
--- a/base/task/thread_pool/thread_pool_impl_unittest.cc
+++ b/base/task/thread_pool/thread_pool_impl_unittest.cc
@@ -13,12 +13,12 @@
 #include <vector>
 
 #include "base/base_switches.h"
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
 #include "base/cfi_buildflags.h"
 #include "base/containers/span.h"
 #include "base/debug/stack_trace.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/raw_ptr.h"
 #include "base/message_loop/message_pump_type.h"
 #include "base/metrics/field_trial.h"
diff --git a/base/task/thread_pool/thread_pool_instance.h b/base/task/thread_pool/thread_pool_instance.h
index 2366076e..a4f78b3 100644
--- a/base/task/thread_pool/thread_pool_instance.h
+++ b/base/task/thread_pool/thread_pool_instance.h
@@ -8,7 +8,7 @@
 #include <memory>
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/gtest_prod_util.h"
 #include "base/strings/string_piece.h"
 #include "base/task/sequenced_task_runner.h"
diff --git a/base/task/thread_pool/thread_pool_perftest.cc b/base/task/thread_pool/thread_pool_perftest.cc
index a29d57d..f0f8cfb 100644
--- a/base/task/thread_pool/thread_pool_perftest.cc
+++ b/base/task/thread_pool/thread_pool_perftest.cc
@@ -8,9 +8,9 @@
 #include <vector>
 
 #include "base/barrier_closure.h"
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/raw_ptr.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/task/thread_pool.h"
diff --git a/base/task/thread_pool/tracked_ref_unittest.cc b/base/task/thread_pool/tracked_ref_unittest.cc
index a846646..2c29b007a 100644
--- a/base/task/thread_pool/tracked_ref_unittest.cc
+++ b/base/task/thread_pool/tracked_ref_unittest.cc
@@ -8,7 +8,7 @@
 #include <utility>
 #include <vector>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/synchronization/atomic_flag.h"
 #include "base/test/test_timeouts.h"
 #include "base/threading/thread.h"
diff --git a/base/task/thread_pool/worker_thread.cc b/base/task/thread_pool/worker_thread.cc
index 645abd2..85fc6e5 100644
--- a/base/task/thread_pool/worker_thread.cc
+++ b/base/task/thread_pool/worker_thread.cc
@@ -12,11 +12,11 @@
 
 #include "base/allocator/partition_allocator/partition_alloc_buildflags.h"
 #include "base/allocator/partition_allocator/partition_alloc_config.h"
-#include "base/callback_helpers.h"
 #include "base/check_op.h"
 #include "base/compiler_specific.h"
 #include "base/debug/alias.h"
 #include "base/feature_list.h"
+#include "base/functional/callback_helpers.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/task/task_features.h"
 #include "base/task/thread_pool/environment_config.h"
diff --git a/base/task/thread_pool/worker_thread_unittest.cc b/base/task/thread_pool/worker_thread_unittest.cc
index fd7e9b7..28cb0e0 100644
--- a/base/task/thread_pool/worker_thread_unittest.cc
+++ b/base/task/thread_pool/worker_thread_unittest.cc
@@ -15,9 +15,9 @@
 #include "base/allocator/partition_allocator/partition_alloc_config.h"
 #include "base/allocator/partition_allocator/shim/allocator_shim.h"
 #include "base/allocator/partition_allocator/shim/allocator_shim_default_dispatch_to_partition_alloc.h"
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/compiler_specific.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
diff --git a/base/task/thread_pool_unittest.cc b/base/task/thread_pool_unittest.cc
index da265c5..4f9d3fe 100644
--- a/base/task/thread_pool_unittest.cc
+++ b/base/task/thread_pool_unittest.cc
@@ -4,7 +4,7 @@
 
 #include "base/task/thread_pool.h"
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/location.h"
 #include "base/run_loop.h"
 #include "base/task/bind_post_task.h"
diff --git a/base/test/bind.cc b/base/test/bind.cc
index e90dd31..707df71 100644
--- a/base/test/bind.cc
+++ b/base/test/bind.cc
@@ -6,8 +6,8 @@
 
 #include <string>
 
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/location.h"
 #include "base/strings/string_piece.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/test/bind.h b/base/test/bind.h
index 1d3b74c..f034763 100644
--- a/base/test/bind.h
+++ b/base/test/bind.h
@@ -8,7 +8,7 @@
 #include <type_traits>
 #include <utility>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/strings/string_piece.h"
 
 namespace base {
diff --git a/base/test/gmock_callback_support.h b/base/test/gmock_callback_support.h
index af8b2cb8..fb99024 100644
--- a/base/test/gmock_callback_support.h
+++ b/base/test/gmock_callback_support.h
@@ -10,7 +10,7 @@
 #include <type_traits>
 #include <utility>
 
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_refptr.h"
 #include "testing/gmock/include/gmock/gmock.h"
diff --git a/base/test/gmock_callback_support_unittest.cc b/base/test/gmock_callback_support_unittest.cc
index 5441c10..e064e0f 100644
--- a/base/test/gmock_callback_support_unittest.cc
+++ b/base/test/gmock_callback_support_unittest.cc
@@ -6,8 +6,8 @@
 
 #include <memory>
 
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/base/test/launcher/test_launcher.cc b/base/test/launcher/test_launcher.cc
index 125470c..98aaabe 100644
--- a/base/test/launcher/test_launcher.cc
+++ b/base/test/launcher/test_launcher.cc
@@ -14,7 +14,6 @@
 #include <utility>
 
 #include "base/at_exit.h"
-#include "base/bind.h"
 #include "base/clang_profiling_buildflags.h"
 #include "base/command_line.h"
 #include "base/containers/adapters.h"
@@ -25,6 +24,7 @@
 #include "base/files/file_util.h"
 #include "base/files/scoped_file.h"
 #include "base/format_macros.h"
+#include "base/functional/bind.h"
 #include "base/hash/hash.h"
 #include "base/lazy_instance.h"
 #include "base/location.h"
diff --git a/base/test/launcher/test_launcher_unittest.cc b/base/test/launcher/test_launcher_unittest.cc
index e534155..6f157ba 100644
--- a/base/test/launcher/test_launcher_unittest.cc
+++ b/base/test/launcher/test_launcher_unittest.cc
@@ -7,11 +7,11 @@
 #include <stddef.h>
 
 #include "base/base64.h"
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/command_line.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/logging.h"
 #include "base/no_destructor.h"
 #include "base/process/launch.h"
diff --git a/base/test/launcher/test_results_tracker.h b/base/test/launcher/test_results_tracker.h
index a304d7b..e25dfa6 100644
--- a/base/test/launcher/test_results_tracker.h
+++ b/base/test/launcher/test_results_tracker.h
@@ -11,7 +11,7 @@
 #include <utility>
 #include <vector>
 
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/test/launcher/test_result.h"
diff --git a/base/test/launcher/unit_test_launcher.cc b/base/test/launcher/unit_test_launcher.cc
index 343a948e..522e95ee 100644
--- a/base/test/launcher/unit_test_launcher.cc
+++ b/base/test/launcher/unit_test_launcher.cc
@@ -9,13 +9,13 @@
 #include <utility>
 
 #include "base/base_switches.h"
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/command_line.h"
 #include "base/compiler_specific.h"
 #include "base/debug/debugger.h"
 #include "base/files/file_util.h"
 #include "base/format_macros.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/message_loop/message_pump_type.h"
diff --git a/base/test/launcher/unit_test_launcher.h b/base/test/launcher/unit_test_launcher.h
index 7f66dbb..38f0eaf 100644
--- a/base/test/launcher/unit_test_launcher.h
+++ b/base/test/launcher/unit_test_launcher.h
@@ -10,9 +10,9 @@
 #include <string>
 #include <vector>
 
-#include "base/callback.h"
 #include "base/files/file_path.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/test/launcher/test_launcher.h"
 #include "build/build_config.h"
diff --git a/base/test/metrics/user_action_tester.cc b/base/test/metrics/user_action_tester.cc
index 3bbcaaa0..5b5e9847 100644
--- a/base/test/metrics/user_action_tester.cc
+++ b/base/test/metrics/user_action_tester.cc
@@ -4,8 +4,8 @@
 
 #include "base/test/metrics/user_action_tester.h"
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/test/test_simple_task_runner.h"
 
 namespace base {
diff --git a/base/test/mock_callback.h b/base/test/mock_callback.h
index 8493ddf..4b7d854 100644
--- a/base/test/mock_callback.h
+++ b/base/test/mock_callback.h
@@ -36,8 +36,8 @@
 #ifndef BASE_TEST_MOCK_CALLBACK_H_
 #define BASE_TEST_MOCK_CALLBACK_H_
 
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
 namespace base {
diff --git a/base/test/mock_callback.h.pump b/base/test/mock_callback.h.pump
index 17f24f1..f0d8c4f 100644
--- a/base/test/mock_callback.h.pump
+++ b/base/test/mock_callback.h.pump
@@ -43,8 +43,8 @@
 #ifndef BASE_TEST_MOCK_CALLBACK_H_
 #define BASE_TEST_MOCK_CALLBACK_H_
 
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
 namespace base {
diff --git a/base/test/mock_callback_unittest.cc b/base/test/mock_callback_unittest.cc
index 61d9dc00..a43e51a 100644
--- a/base/test/mock_callback_unittest.cc
+++ b/base/test/mock_callback_unittest.cc
@@ -4,7 +4,7 @@
 
 #include "base/test/mock_callback.h"
 
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
 using testing::InSequence;
diff --git a/base/test/null_task_runner.h b/base/test/null_task_runner.h
index 390025d..1efc6ab 100644
--- a/base/test/null_task_runner.h
+++ b/base/test/null_task_runner.h
@@ -5,8 +5,8 @@
 #ifndef BASE_TEST_NULL_TASK_RUNNER_H_
 #define BASE_TEST_NULL_TASK_RUNNER_H_
 
-#include "base/callback.h"
 #include "base/compiler_specific.h"
+#include "base/functional/callback.h"
 #include "base/task/single_thread_task_runner.h"
 
 namespace base {
diff --git a/base/test/rectify_callback_unittest.cc b/base/test/rectify_callback_unittest.cc
index 66ec16a..7181e5a5 100644
--- a/base/test/rectify_callback_unittest.cc
+++ b/base/test/rectify_callback_unittest.cc
@@ -7,8 +7,6 @@
 #include <sstream>
 #include <utility>
 
-#include "base/callback.h"
-#include "base/callback_forward.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
 #include "base/functional/callback_forward.h"
diff --git a/base/test/run_all_unittests.cc b/base/test/run_all_unittests.cc
index 572030e..4f0611ac 100644
--- a/base/test/run_all_unittests.cc
+++ b/base/test/run_all_unittests.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 "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/metrics/persistent_histogram_allocator.h"
 #include "base/test/launcher/unit_test_launcher.h"
 #include "base/test/test_suite.h"
diff --git a/base/test/scoped_dev_zero_fuchsia.cc b/base/test/scoped_dev_zero_fuchsia.cc
index 68bd2570..7088070 100644
--- a/base/test/scoped_dev_zero_fuchsia.cc
+++ b/base/test/scoped_dev_zero_fuchsia.cc
@@ -17,10 +17,10 @@
 #include <functional>
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback.h"
 #include "base/check.h"
 #include "base/fuchsia/fuchsia_logging.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/message_loop/message_pump_type.h"
 #include "base/run_loop.h"
 
diff --git a/base/test/scoped_mock_time_message_loop_task_runner.cc b/base/test/scoped_mock_time_message_loop_task_runner.cc
index e4486e4..2ff81f1 100644
--- a/base/test/scoped_mock_time_message_loop_task_runner.cc
+++ b/base/test/scoped_mock_time_message_loop_task_runner.cc
@@ -4,8 +4,8 @@
 
 #include "base/test/scoped_mock_time_message_loop_task_runner.h"
 
-#include "base/bind.h"
 #include "base/check_op.h"
+#include "base/functional/bind.h"
 #include "base/run_loop.h"
 #include "base/task/current_thread.h"
 #include "base/task/single_thread_task_runner.h"
diff --git a/base/test/scoped_mock_time_message_loop_task_runner_unittest.cc b/base/test/scoped_mock_time_message_loop_task_runner_unittest.cc
index 93610d94..e05f374 100644
--- a/base/test/scoped_mock_time_message_loop_task_runner_unittest.cc
+++ b/base/test/scoped_mock_time_message_loop_task_runner_unittest.cc
@@ -6,9 +6,9 @@
 
 #include <memory>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/containers/circular_deque.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/task/current_thread.h"
diff --git a/base/test/scoped_run_loop_timeout.cc b/base/test/scoped_run_loop_timeout.cc
index 39ee1db..7ad61cf 100644
--- a/base/test/scoped_run_loop_timeout.cc
+++ b/base/test/scoped_run_loop_timeout.cc
@@ -4,8 +4,8 @@
 
 #include "base/test/scoped_run_loop_timeout.h"
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/strings/strcat.h"
diff --git a/base/test/scoped_run_loop_timeout.h b/base/test/scoped_run_loop_timeout.h
index a34c5b5..d0e4a19 100644
--- a/base/test/scoped_run_loop_timeout.h
+++ b/base/test/scoped_run_loop_timeout.h
@@ -7,7 +7,7 @@
 
 #include <string>
 
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/gtest_prod_util.h"
 #include "base/location.h"
 #include "base/memory/raw_ptr.h"
diff --git a/base/test/scoped_run_loop_timeout_unittest.cc b/base/test/scoped_run_loop_timeout_unittest.cc
index 20f495f6..1e87d42 100644
--- a/base/test/scoped_run_loop_timeout_unittest.cc
+++ b/base/test/scoped_run_loop_timeout_unittest.cc
@@ -4,8 +4,8 @@
 
 #include "base/test/scoped_run_loop_timeout.h"
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/location.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/test/bind.h"
diff --git a/base/test/sequenced_task_runner_test_template.h b/base/test/sequenced_task_runner_test_template.h
index a495aa7..7a2ec12 100644
--- a/base/test/sequenced_task_runner_test_template.h
+++ b/base/test/sequenced_task_runner_test_template.h
@@ -14,8 +14,8 @@
 #include <iosfwd>
 #include <vector>
 
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/memory/ref_counted.h"
 #include "base/synchronization/condition_variable.h"
 #include "base/synchronization/lock.h"
diff --git a/base/test/task_environment.cc b/base/test/task_environment.cc
index 70dd416..4db778dc 100644
--- a/base/test/task_environment.cc
+++ b/base/test/task_environment.cc
@@ -8,9 +8,9 @@
 #include <memory>
 #include <ostream>
 
-#include "base/callback_helpers.h"
 #include "base/check.h"
 #include "base/debug/stack_trace.h"
+#include "base/functional/callback_helpers.h"
 #include "base/lazy_instance.h"
 #include "base/location.h"
 #include "base/logging.h"
diff --git a/base/test/task_environment_unittest.cc b/base/test/task_environment_unittest.cc
index 8d63331..815e96d 100644
--- a/base/test/task_environment_unittest.cc
+++ b/base/test/task_environment_unittest.cc
@@ -8,11 +8,11 @@
 #include <memory>
 
 #include "base/atomicops.h"
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/cancelable_callback.h"
 #include "base/check.h"
 #include "base/debug/debugger.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/logging.h"
 #include "base/run_loop.h"
 #include "base/synchronization/atomic_flag.h"
diff --git a/base/test/task_runner_test_template.h b/base/test/task_runner_test_template.h
index 653115bc..8eca3b4 100644
--- a/base/test/task_runner_test_template.h
+++ b/base/test/task_runner_test_template.h
@@ -50,8 +50,8 @@
 #include <cstddef>
 #include <map>
 
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/location.h"
 #include "base/memory/ref_counted.h"
 #include "base/synchronization/condition_variable.h"
diff --git a/base/test/test_future.h b/base/test/test_future.h
index 4a48669..13aa0b4 100644
--- a/base/test/test_future.h
+++ b/base/test/test_future.h
@@ -8,9 +8,9 @@
 #include <memory>
 #include <string>
 
-#include "base/bind.h"
-#include "base/callback_forward.h"
 #include "base/check.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_forward.h"
 #include "base/memory/weak_ptr.h"
 #include "base/run_loop.h"
 #include "base/sequence_checker.h"
diff --git a/base/test/test_io_thread.h b/base/test/test_io_thread.h
index e60958a..ce895a1 100644
--- a/base/test/test_io_thread.h
+++ b/base/test/test_io_thread.h
@@ -5,8 +5,8 @@
 #ifndef BASE_TEST_TEST_IO_THREAD_H_
 #define BASE_TEST_TEST_IO_THREAD_H_
 
-#include "base/callback_forward.h"
 #include "base/compiler_specific.h"
+#include "base/functional/callback_forward.h"
 #include "base/memory/ref_counted.h"
 #include "base/task/task_runner.h"
 #include "base/threading/thread.h"
diff --git a/base/test/test_mock_time_task_runner.h b/base/test/test_mock_time_task_runner.h
index d0110619..366b346 100644
--- a/base/test/test_mock_time_task_runner.h
+++ b/base/test/test_mock_time_task_runner.h
@@ -11,9 +11,9 @@
 #include <queue>
 #include <vector>
 
-#include "base/callback.h"
-#include "base/callback_helpers.h"
 #include "base/containers/circular_deque.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
 #include "base/synchronization/condition_variable.h"
diff --git a/base/test/test_mock_time_task_runner_unittest.cc b/base/test/test_mock_time_task_runner_unittest.cc
index 4482495..fb8fd7a1 100644
--- a/base/test/test_mock_time_task_runner_unittest.cc
+++ b/base/test/test_mock_time_task_runner_unittest.cc
@@ -4,9 +4,9 @@
 
 #include "base/test/test_mock_time_task_runner.h"
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/cancelable_callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/ref_counted.h"
 #include "base/run_loop.h"
 #include "base/task/sequenced_task_runner.h"
diff --git a/base/test/test_pending_task.h b/base/test/test_pending_task.h
index e05a80d..7631235 100644
--- a/base/test/test_pending_task.h
+++ b/base/test/test_pending_task.h
@@ -7,7 +7,7 @@
 
 #include <string>
 
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/location.h"
 #include "base/time/time.h"
 #include "base/trace_event/base_tracing_forward.h"
diff --git a/base/test/test_pending_task_unittest.cc b/base/test/test_pending_task_unittest.cc
index 94c5278..96d6235 100644
--- a/base/test/test_pending_task_unittest.cc
+++ b/base/test/test_pending_task_unittest.cc
@@ -4,7 +4,7 @@
 
 #include "base/test/test_pending_task.h"
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/trace_event/base_tracing.h"
 #include "base/tracing_buildflags.h"
 #include "testing/gmock/include/gmock/gmock.h"
diff --git a/base/test/test_simple_task_runner.h b/base/test/test_simple_task_runner.h
index ccd8334..4639ab0 100644
--- a/base/test/test_simple_task_runner.h
+++ b/base/test/test_simple_task_runner.h
@@ -5,9 +5,9 @@
 #ifndef BASE_TEST_TEST_SIMPLE_TASK_RUNNER_H_
 #define BASE_TEST_TEST_SIMPLE_TASK_RUNNER_H_
 
-#include "base/callback.h"
 #include "base/compiler_specific.h"
 #include "base/containers/circular_deque.h"
+#include "base/functional/callback.h"
 #include "base/synchronization/lock.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/test/test_pending_task.h"
diff --git a/base/test/test_suite.cc b/base/test/test_suite.cc
index bbc6f60..c0365ee 100644
--- a/base/test/test_suite.cc
+++ b/base/test/test_suite.cc
@@ -12,7 +12,6 @@
 #include "base/at_exit.h"
 #include "base/base_paths.h"
 #include "base/base_switches.h"
-#include "base/bind.h"
 #include "base/command_line.h"
 #include "base/debug/debugger.h"
 #include "base/debug/profiler.h"
@@ -20,6 +19,7 @@
 #include "base/feature_list.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
+#include "base/functional/bind.h"
 #include "base/i18n/icu_util.h"
 #include "base/i18n/rtl.h"
 #include "base/logging.h"
diff --git a/base/test/test_waitable_event_unittest.cc b/base/test/test_waitable_event_unittest.cc
index ea9dacb..7f501ae 100644
--- a/base/test/test_waitable_event_unittest.cc
+++ b/base/test/test_waitable_event_unittest.cc
@@ -4,7 +4,7 @@
 
 #include "base/test/test_waitable_event.h"
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/task/thread_pool.h"
 #include "base/test/task_environment.h"
 #include "base/threading/scoped_blocking_call_internal.h"
diff --git a/base/test/thread_test_helper.cc b/base/test/thread_test_helper.cc
index c635a6cf..2e41863 100644
--- a/base/test/thread_test_helper.cc
+++ b/base/test/thread_test_helper.cc
@@ -6,7 +6,7 @@
 
 #include <utility>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/location.h"
 #include "base/threading/thread_restrictions.h"
 
diff --git a/base/test/trace_event_analyzer.cc b/base/test/trace_event_analyzer.cc
index 6a91308..d071168 100644
--- a/base/test/trace_event_analyzer.cc
+++ b/base/test/trace_event_analyzer.cc
@@ -9,7 +9,7 @@
 #include <algorithm>
 #include <set>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/json/json_reader.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
diff --git a/base/test/trace_event_analyzer_unittest.cc b/base/test/trace_event_analyzer_unittest.cc
index a77305c..fb08ccaa 100644
--- a/base/test/trace_event_analyzer_unittest.cc
+++ b/base/test/trace_event_analyzer_unittest.cc
@@ -7,7 +7,7 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/memory/ref_counted_memory.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/threading/platform_thread.h"
diff --git a/base/test/trace_to_file.cc b/base/test/trace_to_file.cc
index 69db354..da2fb76 100644
--- a/base/test/trace_to_file.cc
+++ b/base/test/trace_to_file.cc
@@ -5,9 +5,9 @@
 #include "base/test/trace_to_file.h"
 
 #include "base/base_switches.h"
-#include "base/bind.h"
 #include "base/command_line.h"
 #include "base/files/file_util.h"
+#include "base/functional/bind.h"
 #include "base/memory/ref_counted_memory.h"
 #include "base/run_loop.h"
 #include "base/task/single_thread_task_runner.h"
diff --git a/base/threading/counter_perftest.cc b/base/threading/counter_perftest.cc
index 59856032..db3b99d 100644
--- a/base/threading/counter_perftest.cc
+++ b/base/threading/counter_perftest.cc
@@ -6,7 +6,7 @@
 #include <string>
 
 #include "base/barrier_closure.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/synchronization/lock.h"
 #include "base/synchronization/waitable_event.h"
diff --git a/base/threading/hang_watcher.cc b/base/threading/hang_watcher.cc
index 38c60d75..31e0b7d6 100644
--- a/base/threading/hang_watcher.cc
+++ b/base/threading/hang_watcher.cc
@@ -7,14 +7,14 @@
 #include <atomic>
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/containers/flat_map.h"
 #include "base/debug/alias.h"
 #include "base/debug/crash_logging.h"
 #include "base/debug/dump_without_crashing.h"
 #include "base/debug/leak_annotations.h"
 #include "base/feature_list.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/metrics/field_trial_params.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/no_destructor.h"
diff --git a/base/threading/hang_watcher.h b/base/threading/hang_watcher.h
index 2e4aface..410913c 100644
--- a/base/threading/hang_watcher.h
+++ b/base/threading/hang_watcher.h
@@ -14,12 +14,12 @@
 #include "base/atomicops.h"
 #include "base/base_export.h"
 #include "base/bits.h"
-#include "base/callback.h"
-#include "base/callback_forward.h"
-#include "base/callback_helpers.h"
 #include "base/compiler_specific.h"
 #include "base/dcheck_is_on.h"
 #include "base/debug/crash_logging.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_forward.h"
+#include "base/functional/callback_helpers.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/memory_pressure_listener.h"
 #include "base/memory/raw_ptr.h"
diff --git a/base/threading/hang_watcher_unittest.cc b/base/threading/hang_watcher_unittest.cc
index 065fcdc8..960b849 100644
--- a/base/threading/hang_watcher_unittest.cc
+++ b/base/threading/hang_watcher_unittest.cc
@@ -7,9 +7,9 @@
 #include <memory>
 
 #include "base/barrier_closure.h"
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
diff --git a/base/threading/post_task_and_reply_impl.cc b/base/threading/post_task_and_reply_impl.cc
index 88e8cff..fb72de39 100644
--- a/base/threading/post_task_and_reply_impl.cc
+++ b/base/threading/post_task_and_reply_impl.cc
@@ -6,9 +6,9 @@
 
 #include <utility>
 
-#include "base/bind.h"
 #include "base/check_op.h"
 #include "base/debug/leak_annotations.h"
+#include "base/functional/bind.h"
 #include "base/memory/ref_counted.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/task/thread_pool/thread_pool_instance.h"
diff --git a/base/threading/post_task_and_reply_impl.h b/base/threading/post_task_and_reply_impl.h
index 8f1a2a7..9e3fda11 100644
--- a/base/threading/post_task_and_reply_impl.h
+++ b/base/threading/post_task_and_reply_impl.h
@@ -8,7 +8,7 @@
 #define BASE_THREADING_POST_TASK_AND_REPLY_IMPL_H_
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/location.h"
 
 namespace base {
diff --git a/base/threading/post_task_and_reply_impl_unittest.cc b/base/threading/post_task_and_reply_impl_unittest.cc
index f0f55467..e90ea9f 100644
--- a/base/threading/post_task_and_reply_impl_unittest.cc
+++ b/base/threading/post_task_and_reply_impl_unittest.cc
@@ -7,8 +7,8 @@
 #include <utility>
 
 #include "base/auto_reset.h"
-#include "base/bind.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
 #include "base/task/sequenced_task_runner.h"
diff --git a/base/threading/scoped_blocking_call.h b/base/threading/scoped_blocking_call.h
index 7094096b..0242c9a 100644
--- a/base/threading/scoped_blocking_call.h
+++ b/base/threading/scoped_blocking_call.h
@@ -6,7 +6,7 @@
 #define BASE_THREADING_SCOPED_BLOCKING_CALL_H_
 
 #include "base/base_export.h"
-#include "base/callback_forward.h"
+#include "base/functional/callback_forward.h"
 #include "base/location.h"
 #include "base/strings/string_piece.h"
 #include "base/threading/scoped_blocking_call_internal.h"
diff --git a/base/threading/scoped_blocking_call_internal.cc b/base/threading/scoped_blocking_call_internal.cc
index d594778..3128c90 100644
--- a/base/threading/scoped_blocking_call_internal.cc
+++ b/base/threading/scoped_blocking_call_internal.cc
@@ -7,9 +7,9 @@
 #include <algorithm>
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/check_op.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/lazy_instance.h"
 #include "base/no_destructor.h"
 #include "base/numerics/safe_conversions.h"
diff --git a/base/threading/scoped_blocking_call_internal.h b/base/threading/scoped_blocking_call_internal.h
index 25534ff..99c7ab0 100644
--- a/base/threading/scoped_blocking_call_internal.h
+++ b/base/threading/scoped_blocking_call_internal.h
@@ -6,8 +6,8 @@
 #define BASE_THREADING_SCOPED_BLOCKING_CALL_INTERNAL_H_
 
 #include "base/base_export.h"
-#include "base/callback_forward.h"
 #include "base/debug/activity_tracker.h"
+#include "base/functional/callback_forward.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
 #include "base/synchronization/lock.h"
diff --git a/base/threading/scoped_blocking_call_unittest.cc b/base/threading/scoped_blocking_call_unittest.cc
index f12e8c8..f4f29c69 100644
--- a/base/threading/scoped_blocking_call_unittest.cc
+++ b/base/threading/scoped_blocking_call_unittest.cc
@@ -9,8 +9,8 @@
 #include <vector>
 
 #include "base/barrier_closure.h"
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/task/thread_pool.h"
 #include "base/task/thread_pool/environment_config.h"
 #include "base/task/thread_pool/thread_pool_impl.h"
diff --git a/base/threading/thread.cc b/base/threading/thread.cc
index dd69f3a6..174beed2 100644
--- a/base/threading/thread.cc
+++ b/base/threading/thread.cc
@@ -8,8 +8,8 @@
 #include <type_traits>
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/lazy_instance.h"
 #include "base/location.h"
 #include "base/logging.h"
diff --git a/base/threading/thread.h b/base/threading/thread.h
index 859a585..d1a9241 100644
--- a/base/threading/thread.h
+++ b/base/threading/thread.h
@@ -11,8 +11,8 @@
 #include <string>
 
 #include "base/base_export.h"
-#include "base/callback.h"
 #include "base/check.h"
+#include "base/functional/callback.h"
 #include "base/message_loop/message_pump_type.h"
 #include "base/message_loop/timer_slack.h"
 #include "base/sequence_checker.h"
diff --git a/base/threading/thread_checker_unittest.cc b/base/threading/thread_checker_unittest.cc
index 38a0eab..b405bd8 100644
--- a/base/threading/thread_checker_unittest.cc
+++ b/base/threading/thread_checker_unittest.cc
@@ -6,8 +6,8 @@
 
 #include <memory>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/ref_counted.h"
 #include "base/sequence_token.h"
 #include "base/task/single_thread_task_runner.h"
diff --git a/base/threading/thread_id_name_manager.h b/base/threading/thread_id_name_manager.h
index 620bb177..85063c8 100644
--- a/base/threading/thread_id_name_manager.h
+++ b/base/threading/thread_id_name_manager.h
@@ -10,7 +10,7 @@
 #include <vector>
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/synchronization/lock.h"
 #include "base/threading/platform_thread.h"
diff --git a/base/threading/thread_local_storage_perftest.cc b/base/threading/thread_local_storage_perftest.cc
index 5d8f86b..9f5d1c0 100644
--- a/base/threading/thread_local_storage_perftest.cc
+++ b/base/threading/thread_local_storage_perftest.cc
@@ -7,9 +7,9 @@
 #include <vector>
 
 #include "base/barrier_closure.h"
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/raw_ptr.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/test/bind.h"
diff --git a/base/threading/thread_perftest.cc b/base/threading/thread_perftest.cc
index 11ef5e8c..3c623f1 100644
--- a/base/threading/thread_perftest.cc
+++ b/base/threading/thread_perftest.cc
@@ -8,8 +8,8 @@
 #include <vector>
 
 #include "base/base_switches.h"
-#include "base/bind.h"
 #include "base/command_line.h"
+#include "base/functional/bind.h"
 #include "base/location.h"
 #include "base/memory/ptr_util.h"
 #include "base/synchronization/condition_variable.h"
diff --git a/base/threading/thread_restrictions_unittest.cc b/base/threading/thread_restrictions_unittest.cc
index 6e1db8d..846a153 100644
--- a/base/threading/thread_restrictions_unittest.cc
+++ b/base/threading/thread_restrictions_unittest.cc
@@ -6,11 +6,11 @@
 
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback.h"
 #include "base/compiler_specific.h"
 #include "base/dcheck_is_on.h"
 #include "base/debug/stack_trace.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/test/gtest_util.h"
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/threading/thread_unittest.cc b/base/threading/thread_unittest.cc
index 387c90a6..b3b11547 100644
--- a/base/threading/thread_unittest.cc
+++ b/base/threading/thread_unittest.cc
@@ -10,8 +10,8 @@
 #include <utility>
 #include <vector>
 
-#include "base/bind.h"
 #include "base/debug/leak_annotations.h"
+#include "base/functional/bind.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
diff --git a/base/timer/mock_timer_unittest.cc b/base/timer/mock_timer_unittest.cc
index 24cf688..8524cd6 100644
--- a/base/timer/mock_timer_unittest.cc
+++ b/base/timer/mock_timer_unittest.cc
@@ -4,7 +4,7 @@
 
 #include "base/timer/mock_timer.h"
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
diff --git a/base/timer/timer.h b/base/timer/timer.h
index d78485a..4cd6baa 100644
--- a/base/timer/timer.h
+++ b/base/timer/timer.h
@@ -68,9 +68,9 @@
 // should be able to tell the difference.
 
 #include "base/base_export.h"
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/location.h"
 #include "base/memory/raw_ptr.h"
 #include "base/sequence_checker.h"
diff --git a/base/timer/timer_unittest.cc b/base/timer/timer_unittest.cc
index d401321..63ad63e9 100644
--- a/base/timer/timer_unittest.cc
+++ b/base/timer/timer_unittest.cc
@@ -8,9 +8,9 @@
 
 #include <memory>
 
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/ref_counted.h"
 #include "base/run_loop.h"
 #include "base/task/sequenced_task_runner.h"
diff --git a/base/timer/wall_clock_timer.h b/base/timer/wall_clock_timer.h
index 8aa9cb19c..eabfe95f 100644
--- a/base/timer/wall_clock_timer.h
+++ b/base/timer/wall_clock_timer.h
@@ -6,8 +6,8 @@
 #define BASE_TIMER_WALL_CLOCK_TIMER_H_
 
 #include "base/base_export.h"
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/location.h"
 #include "base/memory/raw_ptr.h"
 #include "base/power_monitor/power_observer.h"
diff --git a/base/trace_event/cpufreq_monitor_android.cc b/base/trace_event/cpufreq_monitor_android.cc
index aebba8c..48d773f 100644
--- a/base/trace_event/cpufreq_monitor_android.cc
+++ b/base/trace_event/cpufreq_monitor_android.cc
@@ -6,9 +6,9 @@
 
 #include <fcntl.h>
 
-#include "base/bind.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_file.h"
+#include "base/functional/bind.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/no_destructor.h"
 #include "base/strings/string_number_conversions.h"
diff --git a/base/trace_event/memory_dump_manager_test_utils.h b/base/trace_event/memory_dump_manager_test_utils.h
index d540ef6e..9a231957 100644
--- a/base/trace_event/memory_dump_manager_test_utils.h
+++ b/base/trace_event/memory_dump_manager_test_utils.h
@@ -5,7 +5,7 @@
 #ifndef BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_TEST_UTILS_H_
 #define BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_TEST_UTILS_H_
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/trace_event/memory_dump_manager.h"
 #include "base/trace_event/memory_dump_request_args.h"
 
diff --git a/base/trace_event/memory_dump_manager_unittest.cc b/base/trace_event/memory_dump_manager_unittest.cc
index 6d989f8c..348d21f 100644
--- a/base/trace_event/memory_dump_manager_unittest.cc
+++ b/base/trace_event/memory_dump_manager_unittest.cc
@@ -13,9 +13,9 @@
 #include "base/allocator/buildflags.h"
 #include "base/at_exit.h"
 #include "base/base_switches.h"
-#include "base/bind.h"
-#include "base/callback.h"
 #include "base/command_line.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/run_loop.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/task/sequenced_task_runner.h"
diff --git a/base/trace_event/memory_dump_request_args.h b/base/trace_event/memory_dump_request_args.h
index 32d9e3b..4920535 100644
--- a/base/trace_event/memory_dump_request_args.h
+++ b/base/trace_event/memory_dump_request_args.h
@@ -14,7 +14,7 @@
 #include <string>
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/process/process_handle.h"
 
 namespace base {
diff --git a/base/trace_event/memory_dump_scheduler.cc b/base/trace_event/memory_dump_scheduler.cc
index 77356d5..80d0519 100644
--- a/base/trace_event/memory_dump_scheduler.cc
+++ b/base/trace_event/memory_dump_scheduler.cc
@@ -7,8 +7,8 @@
 #include <algorithm>
 #include <limits>
 
-#include "base/bind.h"
 #include "base/check_op.h"
+#include "base/functional/bind.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/time/time.h"
 
diff --git a/base/trace_event/memory_dump_scheduler.h b/base/trace_event/memory_dump_scheduler.h
index 73d611ce..e480f1f 100644
--- a/base/trace_event/memory_dump_scheduler.h
+++ b/base/trace_event/memory_dump_scheduler.h
@@ -10,7 +10,7 @@
 #include <vector>
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/trace_event/memory_dump_request_args.h"
 
 namespace base {
diff --git a/base/trace_event/memory_dump_scheduler_unittest.cc b/base/trace_event/memory_dump_scheduler_unittest.cc
index c2854f1..6436513 100644
--- a/base/trace_event/memory_dump_scheduler_unittest.cc
+++ b/base/trace_event/memory_dump_scheduler_unittest.cc
@@ -6,7 +6,7 @@
 
 #include <memory>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/threading/thread.h"
diff --git a/base/trace_event/trace_buffer.cc b/base/trace_event/trace_buffer.cc
index 8f8b424..b3b8692 100644
--- a/base/trace_event/trace_buffer.cc
+++ b/base/trace_event/trace_buffer.cc
@@ -8,7 +8,7 @@
 #include <utility>
 #include <vector>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/trace_event/heap_profiler.h"
 #include "base/trace_event/trace_event_impl.h"
 
diff --git a/base/trace_event/trace_category_unittest.cc b/base/trace_event/trace_category_unittest.cc
index 9305ba3..e7b58ef4 100644
--- a/base/trace_event/trace_category_unittest.cc
+++ b/base/trace_event/trace_category_unittest.cc
@@ -6,7 +6,7 @@
 
 #include <memory>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/lazy_instance.h"
 #include "base/synchronization/lock.h"
 #include "base/synchronization/waitable_event.h"
diff --git a/base/trace_event/trace_event_android.cc b/base/trace_event/trace_event_android.cc
index e9f3be80..0d0d436 100644
--- a/base/trace_event/trace_event_android.cc
+++ b/base/trace_event/trace_event_android.cc
@@ -8,8 +8,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "base/bind.h"
 #include "base/format_macros.h"
+#include "base/functional/bind.h"
 #include "base/logging.h"
 #include "base/posix/eintr_wrapper.h"
 #include "base/strings/stringprintf.h"
diff --git a/base/trace_event/trace_event_impl.h b/base/trace_event/trace_event_impl.h
index 12e4040..235c3e2 100644
--- a/base/trace_event/trace_event_impl.h
+++ b/base/trace_event/trace_event_impl.h
@@ -12,7 +12,7 @@
 #include <string>
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/process/process_handle.h"
 #include "base/strings/string_util.h"
 #include "base/threading/platform_thread.h"
diff --git a/base/trace_event/trace_event_unittest.cc b/base/trace_event/trace_event_unittest.cc
index 6d4fdf1..004b5579 100644
--- a/base/trace_event/trace_event_unittest.cc
+++ b/base/trace_event/trace_event_unittest.cc
@@ -17,9 +17,9 @@
 #include <vector>
 
 #include "base/at_exit.h"
-#include "base/bind.h"
 #include "base/command_line.h"
 #include "base/containers/cxx20_erase_vector.h"
+#include "base/functional/bind.h"
 #include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
 #include "base/location.h"
diff --git a/base/trace_event/trace_log.cc b/base/trace_event/trace_log.cc
index f2971ac3..6211eec 100644
--- a/base/trace_event/trace_log.cc
+++ b/base/trace_event/trace_log.cc
@@ -11,11 +11,11 @@
 #include <utility>
 
 #include "base/base_switches.h"
-#include "base/bind.h"
 #include "base/command_line.h"
 #include "base/containers/contains.h"
 #include "base/debug/leak_annotations.h"
 #include "base/format_macros.h"
+#include "base/functional/bind.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
diff --git a/base/trace_event/tracing_agent.h b/base/trace_event/tracing_agent.h
index 4e1451a..4026e33 100644
--- a/base/trace_event/tracing_agent.h
+++ b/base/trace_event/tracing_agent.h
@@ -6,7 +6,7 @@
 #define BASE_TRACE_EVENT_TRACING_AGENT_H_
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/memory/ref_counted_memory.h"
 
 namespace base {
diff --git a/base/tracing/perfetto_task_runner.cc b/base/tracing/perfetto_task_runner.cc
index 5ac8b3b..8022be3c 100644
--- a/base/tracing/perfetto_task_runner.cc
+++ b/base/tracing/perfetto_task_runner.cc
@@ -7,8 +7,8 @@
 #include <memory>
 #include <utility>
 
-#include "base/bind.h"
 #include "base/containers/contains.h"
+#include "base/functional/bind.h"
 #include "base/notreached.h"
 #include "base/task/common/checked_lock_impl.h"
 #include "base/task/common/scoped_defer_task_posting.h"
diff --git a/base/win/async_operation.h b/base/win/async_operation.h
index d708da7..a5217ec 100644
--- a/base/win/async_operation.h
+++ b/base/win/async_operation.h
@@ -13,8 +13,8 @@
 #include <type_traits>
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/memory/weak_ptr.h"
 #include "base/threading/thread_checker.h"
 #include "base/win/winrt_foundation_helpers.h"
diff --git a/base/win/message_window.h b/base/win/message_window.h
index 96329e7..d572c3c 100644
--- a/base/win/message_window.h
+++ b/base/win/message_window.h
@@ -8,8 +8,8 @@
 #include <string>
 
 #include "base/base_export.h"
-#include "base/callback.h"
 #include "base/compiler_specific.h"
+#include "base/functional/callback.h"
 #include "base/threading/thread_checker.h"
 #include "base/win/windows_types.h"
 
diff --git a/base/win/message_window_unittest.cc b/base/win/message_window_unittest.cc
index 4aaad58..c158559 100644
--- a/base/win/message_window_unittest.cc
+++ b/base/win/message_window_unittest.cc
@@ -6,7 +6,7 @@
 
 #include <windows.h>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/guid.h"
 #include "base/strings/utf_string_conversions.h"
 #include "testing/gmock/include/gmock/gmock.h"
diff --git a/base/win/object_watcher.cc b/base/win/object_watcher.cc
index f5a8e9b..bf48b4df 100644
--- a/base/win/object_watcher.cc
+++ b/base/win/object_watcher.cc
@@ -6,7 +6,7 @@
 
 #include <windows.h>
 
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/logging.h"
 #include "base/task/sequenced_task_runner.h"
 
diff --git a/base/win/object_watcher.h b/base/win/object_watcher.h
index 541fba4..22f4ed9 100644
--- a/base/win/object_watcher.h
+++ b/base/win/object_watcher.h
@@ -8,7 +8,7 @@
 #include "base/win/windows_types.h"
 
 #include "base/base_export.h"
-#include "base/callback.h"
+#include "base/functional/callback.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "base/task/sequenced_task_runner.h"
diff --git a/base/win/post_async_results.h b/base/win/post_async_results.h
index de6934a..e5e31f6 100644
--- a/base/win/post_async_results.h
+++ b/base/win/post_async_results.h
@@ -13,8 +13,8 @@
 #include <type_traits>
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/task/bind_post_task.h"
diff --git a/base/win/registry.cc b/base/win/registry.cc
index 1165694b..1ea20fa 100644
--- a/base/win/registry.cc
+++ b/base/win/registry.cc
@@ -13,8 +13,8 @@
 #include <utility>
 #include <vector>
 
-#include "base/callback.h"
 #include "base/check_op.h"
+#include "base/functional/callback.h"
 #include "base/notreached.h"
 #include "base/strings/string_util.h"
 #include "base/strings/string_util_win.h"
diff --git a/base/win/registry.h b/base/win/registry.h
index cef781ae..8037ced 100644
--- a/base/win/registry.h
+++ b/base/win/registry.h
@@ -12,7 +12,7 @@
 #include <vector>
 
 #include "base/base_export.h"
-#include "base/callback_forward.h"
+#include "base/functional/callback_forward.h"
 #include "base/win/windows_types.h"
 
 namespace base {
diff --git a/base/win/registry_unittest.cc b/base/win/registry_unittest.cc
index c52df54..407d8b82 100644
--- a/base/win/registry_unittest.cc
+++ b/base/win/registry_unittest.cc
@@ -12,9 +12,9 @@
 #include <iterator>
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback.h"
 #include "base/compiler_specific.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/location.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/run_loop.h"
diff --git a/build/clobber.py b/build/clobber.py
index 428939a..91927774 100755
--- a/build/clobber.py
+++ b/build/clobber.py
@@ -7,36 +7,119 @@
 
 import argparse
 import os
+import shutil
 import subprocess
 import sys
 
 
-def _generate_build_ninja(build_dir):
-  gn_gen_cmd = ['gn', 'gen', '-C', build_dir]
-  print('Running %s' % ' '.join(gn_gen_cmd))
-  subprocess.run(gn_gen_cmd, check=True)
+def extract_gn_build_commands(build_ninja_file):
+  """Extracts from a build.ninja the commands to run GN.
+
+  The commands to run GN are the gn rule and build.ninja build step at the
+  top of the build.ninja file. We want to keep these when deleting GN builds
+  since we want to preserve the command-line flags to GN.
+
+  On error, returns the empty string."""
+  result = ""
+  with open(build_ninja_file, 'r') as f:
+    # Reads until the first empty line after the "build build.ninja:" target.
+    # We assume everything before it necessary as well (eg the
+    # "ninja_required_version" line).
+    found_build_dot_ninja_target = False
+    for line in f.readlines():
+      result += line
+      if line.startswith('build build.ninja:'):
+        found_build_dot_ninja_target = True
+      if found_build_dot_ninja_target and line[0] == '\n':
+        return result
+  return ''  # We got to EOF and didn't find what we were looking for.
 
 
-def _clean_build_dir(build_dir):
-  print('Cleaning %s' % build_dir)
+def delete_dir(build_dir):
+  if os.path.islink(build_dir):
+    return
+  # For unknown reasons (anti-virus?) rmtree of Chromium build directories
+  # often fails on Windows.
+  if sys.platform.startswith('win'):
+    subprocess.check_call(['rmdir', '/s', '/q', build_dir], shell=True)
+  else:
+    shutil.rmtree(build_dir)
 
-  gn_clean_cmd = ['gn', 'clean', '-C', build_dir]
-  print('Running %s' % ' '.join(gn_clean_cmd))
+
+def delete_build_dir(build_dir):
+  # GN writes a build.ninja.d file. Note that not all GN builds have args.gn.
+  build_ninja_d_file = os.path.join(build_dir, 'build.ninja.d')
+  if not os.path.exists(build_ninja_d_file):
+    delete_dir(build_dir)
+    return
+
+  # GN builds aren't automatically regenerated when you sync. To avoid
+  # messing with the GN workflow, erase everything but the args file, and
+  # write a dummy build.ninja file that will automatically rerun GN the next
+  # time Ninja is run.
+  build_ninja_file = os.path.join(build_dir, 'build.ninja')
+  build_commands = extract_gn_build_commands(build_ninja_file)
+
   try:
-    subprocess.run(gn_clean_cmd, check=True)
-  except Exception:
-    # gn clean may fail when build.ninja is corrupted or missing.
-    # Regenerate build.ninja and retry gn clean again.
-    _generate_build_ninja(build_dir)
-    subprocess.run(gn_clean_cmd, check=True)
+    gn_args_file = os.path.join(build_dir, 'args.gn')
+    with open(gn_args_file, 'r') as f:
+      args_contents = f.read()
+  except IOError:
+    args_contents = ''
+
+  exception_during_rm = None
+  try:
+    # delete_dir and os.mkdir() may fail, such as when chrome.exe is running,
+    # and we still want to restore args.gn/build.ninja/build.ninja.d, so catch
+    # the exception and rethrow it later.
+    delete_dir(build_dir)
+    os.mkdir(build_dir)
+  except Exception as e:
+    exception_during_rm = e
+
+  # Put back the args file (if any).
+  if args_contents != '':
+    with open(gn_args_file, 'w') as f:
+      f.write(args_contents)
+
+  # Write the build.ninja file sufficiently to regenerate itself.
+  with open(os.path.join(build_dir, 'build.ninja'), 'w') as f:
+    if build_commands != '':
+      f.write(build_commands)
+    else:
+      # Couldn't parse the build.ninja file, write a default thing.
+      f.write('''ninja_required_version = 1.7.2
+
+rule gn
+  command = gn -q gen //out/%s/
+  description = Regenerating ninja files
+
+build build.ninja: gn
+  generator = 1
+  depfile = build.ninja.d
+''' % (os.path.split(build_dir)[1]))
+
+  # Write a .d file for the build which references a nonexistant file. This
+  # will make Ninja always mark the build as dirty.
+  with open(build_ninja_d_file, 'w') as f:
+    f.write('build.ninja: nonexistant_file.gn\n')
+
+  if exception_during_rm:
+    # Rethrow the exception we caught earlier.
+    raise exception_during_rm
 
 
 def clobber(out_dir):
-  """Clobber contents of build directory."""
+  """Clobber contents of build directory.
+
+  Don't delete the directory itself: some checkouts have the build directory
+  mounted."""
   for f in os.listdir(out_dir):
     path = os.path.join(out_dir, f)
-    if os.path.isdir(path):
-      _clean_build_dir(path)
+    if os.path.isfile(path):
+      os.unlink(path)
+    elif os.path.isdir(path):
+      delete_build_dir(path)
 
 
 def main():
diff --git a/build/clobber_unittest.py b/build/clobber_unittest.py
index 990926c..908718d 100755
--- a/build/clobber_unittest.py
+++ b/build/clobber_unittest.py
@@ -7,33 +7,125 @@
 import pathlib
 import shutil
 import tempfile
+import textwrap
 import unittest
+from unittest import mock
 
 import clobber
 
 
-class TestClean(unittest.TestCase):
+class TestExtractBuildCommand(unittest.TestCase):
+  def setUp(self):
+    _, self.build_ninja_path = tempfile.mkstemp(text=True)
+
+  def tearDown(self):
+    os.remove(self.build_ninja_path)
+
+  def test_normal_extraction(self):
+    build_ninja_file_contents = textwrap.dedent("""
+        ninja_required_version = 1.7.2
+
+        rule gn
+          command = ../../buildtools/gn --root=../.. -q --regeneration gen .
+          pool = console
+          description = Regenerating ninja files
+
+        build build.ninja.stamp: gn
+          generator = 1
+          depfile = build.ninja.d
+
+        build build.ninja: phony build.ninja.stamp
+          generator = 1
+
+        pool build_toolchain_action_pool
+          depth = 72
+
+        pool build_toolchain_link_pool
+          depth = 23
+
+        subninja toolchain.ninja
+        subninja clang_newlib_x64/toolchain.ninja
+        subninja glibc_x64/toolchain.ninja
+        subninja irt_x64/toolchain.ninja
+        subninja nacl_bootstrap_x64/toolchain.ninja
+        subninja newlib_pnacl/toolchain.ninja
+
+        build blink_python_tests: phony obj/blink_python_tests.stamp
+        build blink_tests: phony obj/blink_tests.stamp
+
+        default all
+    """)  # Based off of a standard linux build dir.
+    with open(self.build_ninja_path, 'w') as f:
+      f.write(build_ninja_file_contents)
+
+    expected_build_ninja_file_contents = textwrap.dedent("""
+        ninja_required_version = 1.7.2
+
+        rule gn
+          command = ../../buildtools/gn --root=../.. -q --regeneration gen .
+          pool = console
+          description = Regenerating ninja files
+
+        build build.ninja.stamp: gn
+          generator = 1
+          depfile = build.ninja.d
+
+        build build.ninja: phony build.ninja.stamp
+          generator = 1
+
+    """)
+
+    self.assertEqual(clobber.extract_gn_build_commands(self.build_ninja_path),
+                     expected_build_ninja_file_contents)
+
+  def test_unexpected_format(self):
+    # No "build build.ninja:" line should make it return an empty string.
+    build_ninja_file_contents = textwrap.dedent("""
+        ninja_required_version = 1.7.2
+
+        rule gn
+          command = ../../buildtools/gn --root=../.. -q --regeneration gen .
+          pool = console
+          description = Regenerating ninja files
+
+        subninja toolchain.ninja
+
+        build blink_python_tests: phony obj/blink_python_tests.stamp
+        build blink_tests: phony obj/blink_tests.stamp
+
+    """)
+    with open(self.build_ninja_path, 'w') as f:
+      f.write(build_ninja_file_contents)
+
+    self.assertEqual(clobber.extract_gn_build_commands(self.build_ninja_path),
+                     '')
+
+
+class TestDelete(unittest.TestCase):
   def setUp(self):
     self.build_dir = tempfile.mkdtemp()
 
+    pathlib.Path(os.path.join(self.build_dir, 'build.ninja')).touch()
+    pathlib.Path(os.path.join(self.build_dir, 'build.ninja.d')).touch()
+
   def tearDown(self):
     shutil.rmtree(self.build_dir)
 
-  def test_gn_clean_ok(self):
-    pathlib.Path(os.path.join(self.build_dir, 'build.ninja')).touch()
-    pathlib.Path(os.path.join(self.build_dir, 'build.ninja.d')).touch()
-
+  def test_delete_build_dir_full(self):
     # Create a dummy file in the build dir and ensure it gets removed.
     dummy_file = os.path.join(self.build_dir, 'dummy')
     pathlib.Path(dummy_file).touch()
 
-    clobber._clean_build_dir(self.build_dir)
+    clobber.delete_build_dir(self.build_dir)
+
     self.assertFalse(os.path.exists(dummy_file))
 
-  def test_gn_clean_fail(self):
-    # gn clean fails without build.ninja.
-    # clean_build_dir() regenerates build.ninja internally.
-    clobber._clean_build_dir(self.build_dir)
+  def test_delete_build_dir_fail(self):
+    # Make delete_dir() throw to ensure it's handled gracefully.
+
+    with mock.patch('clobber.delete_dir', side_effect=OSError):
+      with self.assertRaises(OSError):
+        clobber.delete_build_dir(self.build_dir)
 
 
 if __name__ == '__main__':
diff --git a/chrome/VERSION b/chrome/VERSION
index 84e896ca5..07f7135 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=111
 MINOR=0
-BUILD=5537
+BUILD=5538
 PATCH=0
diff --git a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
index 2192a4d..c246a90 100644
--- a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
+++ b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
@@ -698,6 +698,7 @@
     @Feature({"StartSurface"})
     @EnableFeatures(ChromeFeatureList.START_SURFACE_REFACTOR)
     @CommandLineFlags.Add({START_SURFACE_TEST_SINGLE_ENABLED_PARAMS})
+    @DisabledTest(message = "Flaky, crbug.com/1407193")
     public void testShow_SingleAsHomepage_DoNotResetScrollPositionFromBack() {
         assumeTrue(mImmediateReturn);
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
index 5c2c04c..5603ef67 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -2926,7 +2926,7 @@
         if (currentTab.isIncognito()) mTabModelSelector.selectModel(/*incognito=*/false);
 
         if (StartSurfaceUserData.getKeepTab(currentTab)
-                || ReturnToChromeUtil.isTabFromStartSurface(currentTab)) {
+                || StartSurfaceUserData.isOpenedFromStart(currentTab)) {
             // If the current tab is created from the start surface with the keepTab property,
             // shows the Start surface non-incognito homepage to prevent a loop between the
             // current tab and previous overview mode. Once in the Start surface, it will close
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java
index 7066181..8d26f30 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java
@@ -82,7 +82,6 @@
 import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils;
 import org.chromium.components.embedder_support.util.UrlConstants;
 import org.chromium.components.embedder_support.util.UrlUtilities;
-import org.chromium.components.power_bookmarks.PowerBookmarkMeta;
 import org.chromium.components.webapk.lib.client.WebApkValidator;
 import org.chromium.components.webapps.AppBannerManager;
 import org.chromium.components.webapps.WebappsUtils;
@@ -1175,14 +1174,6 @@
             return;
         }
 
-        PowerBookmarkMeta existingBookmarkMeta = PowerBookmarkUtils.getBookmarkBookmarkMetaForTab(
-                mBookmarkModelSupplier.get(), currentTab);
-        if (existingBookmarkMeta != null && !existingBookmarkMeta.hasShoppingSpecifics()) {
-            startPriceTrackingMenuItem.setVisible(false);
-            stopPriceTrackingMenuItem.setVisible(false);
-            return;
-        }
-
         mIsTypeSpecificBookmarkItemRowPresent = true;
 
         boolean editEnabled = mBookmarkModelSupplier.get().isEditBookmarksEnabled();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
index 2b6222d..09eb9e8 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
@@ -100,6 +100,7 @@
                 add(ChromeFeatureList.sFeedLoadingPlaceholder);
                 add(ChromeFeatureList.sFoldableJankFix);
                 add(ChromeFeatureList.sGridTabSwitcherForTablets);
+                add(ChromeFeatureList.sHideNonDisplayableAccountEmail);
                 add(ChromeFeatureList.sIncognitoReauthenticationForAndroid);
                 add(ChromeFeatureList.sInstanceSwitcher);
                 add(ChromeFeatureList.sInstantStart);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java
index 95c4dd9..c312346 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java
@@ -594,7 +594,14 @@
         mSyncEverything.setChecked(syncEverything);
         if (syncEverything) {
             for (CheckBoxPreference pref : mSyncTypePreferences) {
-                pref.setChecked(true);
+                // TODO(https://crbug.com/1407184): Remove this special-casing
+                //  SyncPaymentsIntegration is not checked for child users as it is disabled
+                if (pref.equals(mSyncPaymentsIntegration)
+                        && !PersonalDataManager.isPaymentsIntegrationEnabled()) {
+                    pref.setChecked(false);
+                } else {
+                    pref.setChecked(true);
+                }
                 pref.setEnabled(false);
             }
             return;
@@ -620,7 +627,8 @@
         boolean syncAutofill = syncTypes.contains(UserSelectableType.AUTOFILL);
         mSyncPaymentsIntegration.setChecked(
                 syncAutofill && PersonalDataManager.isPaymentsIntegrationEnabled());
-        mSyncPaymentsIntegration.setEnabled(syncAutofill);
+        mSyncPaymentsIntegration.setEnabled(
+                syncAutofill && !Profile.getLastUsedRegularProfile().isChild());
     }
 
     /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFirstRunFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFirstRunFragmentTest.java
index 6f7b29a..6bf40ee 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFirstRunFragmentTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFirstRunFragmentTest.java
@@ -71,6 +71,7 @@
 import org.chromium.chrome.browser.firstrun.FirstRunUtilsJni;
 import org.chromium.chrome.browser.firstrun.MobileFreProgress;
 import org.chromium.chrome.browser.firstrun.PolicyLoadListener;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.privacy.settings.PrivacyPreferencesManagerImpl;
 import org.chromium.chrome.browser.profiles.Profile;
@@ -255,7 +256,8 @@
         mSigninTestRule.addAccount(
                 CHILD_ACCOUNT_EMAIL, CHILD_FULL_NAME, /* givenName= */ null, /* avatar= */ null);
 
-        checkFragmentWithChildAccount();
+        checkFragmentWithChildAccount(
+                /* hasDisplayableFullName= */ true, /* hasDisplayableEmail= */ true);
     }
 
     @Test
@@ -455,7 +457,34 @@
 
         launchActivityWithFragment();
 
-        checkFragmentWithChildAccount();
+        checkFragmentWithChildAccount(
+                /* hasDisplayableFullName= */ true, /* hasDisplayableEmail= */ true);
+    }
+
+    @Test
+    @MediumTest
+    public void testFragmentWithChildAccountWithNonDisplayableAccountEmail() {
+        ChromeFeatureList.sHideNonDisplayableAccountEmail.setForTesting(true);
+        mSigninTestRule.addAccount(CHILD_ACCOUNT_EMAIL, CHILD_FULL_NAME, /* givenName= */ null,
+                /* avatar= */ null, SigninTestRule.NON_DISPLAYABLE_EMAIL_ACCOUNT_CAPABILITIES);
+
+        launchActivityWithFragment();
+
+        checkFragmentWithChildAccount(
+                /* hasDisplayableFullName= */ true, /* hasDisplayableEmail= */ false);
+    }
+
+    @Test
+    @MediumTest
+    public void testFragmentWithChildAccountWithNonDisplayableAccountEmailWithEmptyDisplayName() {
+        ChromeFeatureList.sHideNonDisplayableAccountEmail.setForTesting(true);
+        mSigninTestRule.addAccount(CHILD_ACCOUNT_EMAIL, /* fullName= */ null, /* givenName= */ null,
+                /* avatar= */ null, SigninTestRule.NON_DISPLAYABLE_EMAIL_ACCOUNT_CAPABILITIES);
+
+        launchActivityWithFragment();
+
+        checkFragmentWithChildAccount(
+                /* hasDisplayableFullName= */ false, /* hasDisplayableEmail= */ false);
     }
 
     @Test
@@ -612,18 +641,43 @@
 
         mSigninTestRule.addAccount(
                 CHILD_ACCOUNT_EMAIL, CHILD_FULL_NAME, /* givenName= */ null, /* avatar= */ null);
-        launchActivityWithFragment();
-        final String continueAsText = mActivityTestRule.getActivity().getString(
-                R.string.sync_promo_continue_as, CHILD_FULL_NAME);
 
-        onView(withText(continueAsText)).perform(click());
+        checkContinueButtonWithChildAccount(/* hasFullNameInButtonText = */ true);
+    }
 
-        verify(mFirstRunPageDelegateMock).acceptTermsOfService(true);
-        verify(mFirstRunPageDelegateMock).advanceToNextPage();
+    @Test
+    @MediumTest
+    public void testContinueButtonWithChildAccountWithNonDisplayableAccountEmail() {
+        ChromeFeatureList.sHideNonDisplayableAccountEmail.setForTesting(true);
+        IdentityServicesProvider.setInstanceForTests(mIdentityServicesProviderMock);
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            when(IdentityServicesProvider.get().getSigninManager(
+                         Profile.getLastUsedRegularProfile()))
+                    .thenReturn(mSigninManagerMock);
+        });
 
-        // Sign-in isn't processed by SigninFirstRunFragment for child accounts.
-        verify(mSigninManagerMock, never()).signin(any(), any());
-        verify(mSigninManagerMock, never()).signinAndEnableSync(anyInt(), any(), any());
+        mSigninTestRule.addAccount(CHILD_ACCOUNT_EMAIL, CHILD_FULL_NAME, /* givenName= */ null,
+                /* avatar= */ null, SigninTestRule.NON_DISPLAYABLE_EMAIL_ACCOUNT_CAPABILITIES);
+
+        checkContinueButtonWithChildAccount(/* hasFullNameInButtonText = */ true);
+    }
+
+    @Test
+    @MediumTest
+    public void
+    testContinueButtonWithChildAccountWithNonDisplayableAccountEmailWithEmptyDisplayName() {
+        ChromeFeatureList.sHideNonDisplayableAccountEmail.setForTesting(true);
+        IdentityServicesProvider.setInstanceForTests(mIdentityServicesProviderMock);
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            when(IdentityServicesProvider.get().getSigninManager(
+                         Profile.getLastUsedRegularProfile()))
+                    .thenReturn(mSigninManagerMock);
+        });
+
+        mSigninTestRule.addAccount(CHILD_ACCOUNT_EMAIL, /* fullName= */ null, /* givenName= */ null,
+                /* avatar= */ null, SigninTestRule.NON_DISPLAYABLE_EMAIL_ACCOUNT_CAPABILITIES);
+
+        checkContinueButtonWithChildAccount(/* hasFullNameInButtonText = */ false);
     }
 
     @Test
@@ -1090,7 +1144,8 @@
         verify(mPolicyLoadListenerMock, atLeastOnce()).onAvailable(notNull());
     }
 
-    private void checkFragmentWithChildAccount() {
+    private void checkFragmentWithChildAccount(
+            boolean hasDisplayableFullName, boolean hasDisplayableEmail) {
         CriteriaHelper.pollUiThread(
                 mFragment.getView().findViewById(R.id.signin_fre_selected_account)::isShown);
         verify(mFirstRunPageDelegateMock).recordNativePolicyAndChildStatusLoadedHistogram();
@@ -1098,18 +1153,45 @@
         onView(withId(R.id.subtitle)).check(matches(not(isDisplayed())));
         Assert.assertFalse(
                 mFragment.getView().findViewById(R.id.signin_fre_selected_account).isEnabled());
-        onView(withText(CHILD_ACCOUNT_EMAIL)).check(matches(isDisplayed()));
-        onView(withText(CHILD_FULL_NAME)).check(matches(isDisplayed()));
+        if (hasDisplayableEmail) {
+            onView(withText(CHILD_ACCOUNT_EMAIL)).check(matches(isDisplayed()));
+        } else {
+            onView(withText(CHILD_ACCOUNT_EMAIL)).check(doesNotExist());
+        }
+        if (hasDisplayableFullName) {
+            onView(withText(CHILD_FULL_NAME)).check(matches(isDisplayed()));
+        } else {
+            onView(withText(mFragment.getString(R.string.default_google_account_username)))
+                    .check(matches(isDisplayed()));
+        }
         onView(withId(R.id.signin_fre_selected_account_expand_icon))
                 .check(matches(not(isDisplayed())));
-        final String continueAsText =
-                mFragment.getString(R.string.sync_promo_continue_as, CHILD_FULL_NAME);
+        final String continueAsText = hasDisplayableFullName
+                ? mFragment.getString(R.string.sync_promo_continue_as, CHILD_FULL_NAME)
+                : mFragment.getString(R.string.sync_promo_continue);
         onView(withText(continueAsText)).check(matches(isDisplayed()));
         onView(withId(R.id.signin_fre_footer)).check(matches(isDisplayed()));
         onView(withText(R.string.signin_fre_dismiss_button)).check(matches(not(isDisplayed())));
         onView(withId(R.id.fre_browser_managed_by_organization)).check(matches(not(isDisplayed())));
     }
 
+    private void checkContinueButtonWithChildAccount(boolean hasFullNameInButtonText) {
+        launchActivityWithFragment();
+        final String continueAsText = hasFullNameInButtonText
+                ? mActivityTestRule.getActivity().getString(
+                        R.string.sync_promo_continue_as, CHILD_FULL_NAME)
+                : mActivityTestRule.getActivity().getString(R.string.sync_promo_continue);
+
+        onView(withText(continueAsText)).perform(click());
+
+        verify(mFirstRunPageDelegateMock).acceptTermsOfService(true);
+        verify(mFirstRunPageDelegateMock).advanceToNextPage();
+
+        // Sign-in isn't processed by SigninFirstRunFragment for child accounts.
+        verify(mSigninManagerMock, never()).signin(any(), any());
+        verify(mSigninManagerMock, never()).signinAndEnableSync(anyInt(), any(), any());
+    }
+
     private void checkFragmentWhenSigninIsDisabledByPolicy() {
         CriteriaHelper.pollUiThread(() -> {
             return !mFragment.getView().findViewById(R.id.signin_fre_selected_account).isShown();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ManageSyncSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ManageSyncSettingsTest.java
index 6a6531a..ff365e2 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ManageSyncSettingsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ManageSyncSettingsTest.java
@@ -496,6 +496,32 @@
         Assert.assertFalse(pcdf.isResumed());
     }
 
+    @Test
+    @SmallTest
+    @Feature({"Sync"})
+    public void testPaymentIntegrationDisabledForChildUser() {
+        mSyncTestRule.setUpChildAccountAndEnableSyncForTesting();
+        ManageSyncSettings fragment = startManageSyncPreferences();
+        CheckBoxPreference paymentsIntegration = (CheckBoxPreference) fragment.findPreference(
+                ManageSyncSettings.PREF_SYNC_PAYMENTS_INTEGRATION);
+
+        assertSyncOnState(fragment);
+
+        // Payments integration should be disabled even though Sync Everything is on
+        assertPaymentsIntegrationEnabled(false);
+        Assert.assertFalse(paymentsIntegration.isChecked());
+        Assert.assertFalse(paymentsIntegration.isEnabled());
+
+        // Turn off Sync Everything
+        ChromeSwitchPreference syncEverything = getSyncEverything(fragment);
+        mSyncTestRule.togglePreference(syncEverything);
+
+        // Payments integration should stay off
+        assertPaymentsIntegrationEnabled(false);
+        Assert.assertFalse(paymentsIntegration.isChecked());
+        Assert.assertFalse(paymentsIntegration.isEnabled());
+    }
+
     /**
      * Test the trusted vault key retrieval flow, which involves launching an intent and finally
      * calling TrustedVaultClient.notifyKeysChanged().
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/dom_distiller/ReaderModeToolbarButtonControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/dom_distiller/ReaderModeToolbarButtonControllerTest.java
index 37642c93..38ae09d 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/dom_distiller/ReaderModeToolbarButtonControllerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/dom_distiller/ReaderModeToolbarButtonControllerTest.java
@@ -12,7 +12,6 @@
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
 
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -81,29 +80,4 @@
 
         verify(mMockReaderModeManager).activateReaderMode();
     }
-
-    @Test
-    public void testSwapButtonModeSetsIphCommandBuilder() {
-        ReaderModeToolbarButtonController controller = createController();
-
-        ButtonData readerModeButton = controller.get(mMockTab);
-
-        Assert.assertNotNull(readerModeButton.getButtonSpec().getIPHCommandBuilder());
-    }
-
-    @Test
-    public void testActionChipModeSetsNoIphCommandBuilder() {
-        // Set field trial param to use action chip variant.
-        mTestValues.addFeatureFlagOverride(
-                ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION_V2, true);
-        mTestValues.addFieldTrialParamOverride(
-                ChromeFeatureList.CONTEXTUAL_PAGE_ACTION_READER_MODE, "action_chip", "true");
-
-        ReaderModeToolbarButtonController controller = createController();
-
-        ButtonData readerModeButton = controller.get(mMockTab);
-
-        // IPH command builder should not be set on action chip variant.
-        Assert.assertNull(readerModeButton.getButtonSpec().getIPHCommandBuilder());
-    }
 }
diff --git a/chrome/app/DEPS b/chrome/app/DEPS
index d6123212..0791950 100644
--- a/chrome/app/DEPS
+++ b/chrome/app/DEPS
@@ -45,7 +45,6 @@
   "+content/public/common",
   "+extensions/buildflags/buildflags.h",
   "+extensions/common/constants.h",
-  "+headless/app/headless_shell_switches.h",
   "+headless/public",
   "+media/base/media_switches.h",
   "+native_client/src/trusted/service_runtime/osx",
diff --git a/chrome/app/chrome_main.cc b/chrome/app/chrome_main.cc
index 146cf60..059813b5 100644
--- a/chrome/app/chrome_main.cc
+++ b/chrome/app/chrome_main.cc
@@ -19,8 +19,8 @@
 #include "chrome/common/profiler/main_thread_stack_sampling_profiler.h"
 #include "content/public/app/content_main.h"
 #include "content/public/common/content_switches.h"
-#include "headless/app/headless_shell_switches.h"
 #include "headless/public/headless_shell.h"
+#include "headless/public/switches.h"
 
 #if BUILDFLAG(IS_MAC)
 #include "chrome/app/chrome_main_mac.h"
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 3f5c79e..e1c16f89 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -6045,6 +6045,21 @@
     deps += [ "//chrome/browser/enterprise/connectors/device_trust/key_management/core/mac" ]
   }
 
+  if (is_linux || is_win || is_mac || is_android) {
+    sources += [
+      "enterprise/idle/action.cc",
+      "enterprise/idle/action.h",
+      "enterprise/idle/action_runner.cc",
+      "enterprise/idle/action_runner.h",
+      "enterprise/idle/idle_service.cc",
+      "enterprise/idle/idle_service.h",
+      "enterprise/idle/idle_service_factory.cc",
+      "enterprise/idle/idle_service_factory.h",
+      "enterprise/idle/idle_timeout_policy_handler.cc",
+      "enterprise/idle/idle_timeout_policy_handler.h",
+    ]
+  }
+
   if (is_linux || is_win || is_mac) {
     sources += [
       "enterprise/chrome_browser_main_extra_parts_enterprise.cc",
@@ -6067,18 +6082,8 @@
       "enterprise/connectors/device_trust/browser/browser_device_trust_connector_service.h",
       "enterprise/connectors/device_trust/signals/decorators/browser/browser_signals_decorator.cc",
       "enterprise/connectors/device_trust/signals/decorators/browser/browser_signals_decorator.h",
-      "enterprise/idle/action.cc",
-      "enterprise/idle/action.h",
-      "enterprise/idle/action_runner.cc",
-      "enterprise/idle/action_runner.h",
       "enterprise/idle/browser_closer.cc",
       "enterprise/idle/browser_closer.h",
-      "enterprise/idle/idle_service.cc",
-      "enterprise/idle/idle_service.h",
-      "enterprise/idle/idle_service_factory.cc",
-      "enterprise/idle/idle_service_factory.h",
-      "enterprise/idle/idle_timeout_policy_handler.cc",
-      "enterprise/idle/idle_timeout_policy_handler.h",
       "enterprise/remote_commands/rotate_attestation_credential_job.cc",
       "enterprise/remote_commands/rotate_attestation_credential_job.h",
       "enterprise/signals/signals_aggregator_factory.cc",
@@ -7710,7 +7715,6 @@
     deps += [
       "//chrome/browser/resources/media_router/internals:build_ts",
       "//chrome/browser/share/core/resources:make_share_targets_protobuf",
-      "//chrome/browser/ui/webui/web_app_internals:mojo_bindings_js",
     ]
   }
   if (is_chromeos_ash) {
@@ -7739,8 +7743,6 @@
       "//chrome/browser/ui/webui/ash/parent_access:mojo_bindings_js",
       "//chrome/browser/ui/webui/ash/vm:mojo_bindings_js__generator",
       "//chrome/browser/ui/webui/settings/ash:mojom_js",
-      "//chrome/browser/ui/webui/settings/ash/os_apps_page/mojom:mojom_js",
-      "//ui/webui/resources/cr_components/app_management:mojo_bindings_js",
     ]
   }
 
@@ -7779,13 +7781,11 @@
   ]
 
   deps = [
-    "//chrome/browser/media:mojo_bindings_js",
     "//chrome/browser/resources/accessibility:build_ts",
     "//chrome/browser/resources/components:build_ts",
     "//chrome/browser/resources/engagement:build_ts",
     "//chrome/browser/resources/memory_internals:build_ts",
     "//chrome/browser/resources/predictors:build_ts",
-    "//chrome/browser/ui/webui/internals/user_education:mojo_bindings_js",
   ]
 
   if (is_android || is_linux || is_chromeos || is_win) {
diff --git a/chrome/browser/ash/accessibility/spoken_feedback_browsertest.cc b/chrome/browser/ash/accessibility/spoken_feedback_browsertest.cc
index 3ec1878..342f15b 100644
--- a/chrome/browser/ash/accessibility/spoken_feedback_browsertest.cc
+++ b/chrome/browser/ash/accessibility/spoken_feedback_browsertest.cc
@@ -371,7 +371,9 @@
 
 // Tests that clicking the notification center tray does not crash when spoken
 // feedback is enabled.
-IN_PROC_BROWSER_TEST_F(NotificationCenterSpokenFeedbackTest, OpenBubble) {
+// TODO(crbug.com/1407232): Fix flaky timeouts and re-enable.
+IN_PROC_BROWSER_TEST_F(NotificationCenterSpokenFeedbackTest,
+                       DISABLED_OpenBubble) {
   // Enable spoken feedback and add a notification to ensure the tray is
   // visible.
   EnableChromeVox();
diff --git a/chrome/browser/ash/arc/input_overlay/test/arc_test_window.cc b/chrome/browser/ash/arc/input_overlay/test/arc_test_window.cc
index 036edbd..e456a8b 100644
--- a/chrome/browser/ash/arc/input_overlay/test/arc_test_window.cc
+++ b/chrome/browser/ash/arc/input_overlay/test/arc_test_window.cc
@@ -14,13 +14,14 @@
 
 ArcTestWindow::ArcTestWindow(exo::test::ExoTestHelper* helper,
                              aura::Window* root,
-                             const std::string& package_name) {
+                             const std::string& package_name,
+                             const gfx::Rect bounds) {
   shell_surface_ = exo::test::ShellSurfaceBuilder({100, 100})
                        .SetApplicationId(package_name.c_str())
                        .BuildClientControlledShellSurface();
   auto display_id =
       display::Screen::GetScreen()->GetDisplayNearestWindow(root).id();
-  shell_surface_->SetBounds(display_id, gfx::Rect(10, 10, 100, 100));
+  shell_surface_->SetBounds(display_id, bounds);
   surface_ = shell_surface_->root_surface();
   surface_->Commit();
   shell_surface_->GetWidget()->GetNativeWindow()->SetProperty(
diff --git a/chrome/browser/ash/arc/input_overlay/test/arc_test_window.h b/chrome/browser/ash/arc/input_overlay/test/arc_test_window.h
index 76161e5..7168290 100644
--- a/chrome/browser/ash/arc/input_overlay/test/arc_test_window.h
+++ b/chrome/browser/ash/arc/input_overlay/test/arc_test_window.h
@@ -17,7 +17,8 @@
  public:
   ArcTestWindow(exo::test::ExoTestHelper* helper,
                 aura::Window* root,
-                const std::string& package_name);
+                const std::string& package_name,
+                const gfx::Rect bounds=gfx::Rect(10, 10, 100, 100));
   ArcTestWindow(const ArcTestWindow&) = delete;
   ArcTestWindow& operator=(const ArcTestWindow&) = delete;
   ~ArcTestWindow();
diff --git a/chrome/browser/ash/arc/input_overlay/ui/input_menu_view.cc b/chrome/browser/ash/arc/input_overlay/ui/input_menu_view.cc
index 35968af9..ecfcf37 100644
--- a/chrome/browser/ash/arc/input_overlay/ui/input_menu_view.cc
+++ b/chrome/browser/ash/arc/input_overlay/ui/input_menu_view.cc
@@ -51,7 +51,7 @@
 constexpr int kMenuWidthSmall = 280;
 constexpr int kMenuHeight = 244;
 constexpr int kMenuMarginRight = 32;
-constexpr int kMenuMarginRightSmall = 24;
+constexpr int kMenuMarginSmall = 24;
 
 // Individual entries and header.
 constexpr int kHeaderMinHeight = 64;
@@ -106,7 +106,7 @@
 }
 
 int GetMenuMarginRight(int parent_width) {
-  return parent_width < kParentWidthThreshold ? kMenuMarginRightSmall
+  return parent_width < kParentWidthThreshold ? kMenuMarginSmall
                                               : kMenuMarginRight;
 }
 
@@ -354,18 +354,16 @@
   SetSize(gfx::Size(menu_width, kMenuHeight));
   int x = std::max(0, parent_size.width() - width() -
                           GetMenuMarginRight(parent_size.width()));
-  if (x < GetMenuMarginRight(parent_size.width())) {
-    // Set the menu in the middle if there is not enough margin on the left
-    // side.
+  // Set the menu in the middle if there is not enough margin on the left
+  // side.
+  if (x < GetMenuMarginRight(parent_size.width()))
     x = std::max(0, (parent_size.width() - width()) / 2);
-  }
+
   int y = entry_view_->y();
-  if (display_overlay_controller_->touch_injector()->allow_reposition() &&
-      (y + height() > parent_size.height())) {
-    // Set the menu at the bottom if there is not enough margin on the bottom
-    // side.
-    y = parent_size.height() - height();
-  }
+  // Set the menu at the bottom if there is not enough margin on the bottom
+  // side.
+  if (y + height() > parent_size.height())
+    y = std::max(0, parent_size.height() - height() - kMenuMarginSmall);
   SetPosition(gfx::Point(x, y));
 }
 
diff --git a/chrome/browser/ash/arc/input_overlay/ui/menu_entry_view_unittest.cc b/chrome/browser/ash/arc/input_overlay/ui/menu_entry_view_unittest.cc
index 7de4c7b..3fd12b5 100644
--- a/chrome/browser/ash/arc/input_overlay/ui/menu_entry_view_unittest.cc
+++ b/chrome/browser/ash/arc/input_overlay/ui/menu_entry_view_unittest.cc
@@ -70,7 +70,7 @@
   void ReleaseLeftMouseAtMenuEntryView() {
     menu_entry_view_ = display_overlay_controller_->GetMenuEntryView();
     menu_entry_view_->OnMouseReleased(
-        ui::MouseEvent(ui::ET_MOUSE_RELEASED, local_location_, local_location_,
+        ui::MouseEvent(ui::ET_MOUSE_RELEASED, gfx::Point(), gfx::Point(),
                        ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
                        ui::EF_LEFT_MOUSE_BUTTON));
   }
@@ -126,7 +126,7 @@
     exo::test::ExoTestBase::SetUp();
     arc_test_window_ = std::make_unique<test::ArcTestWindow>(
         exo_test_helper(), ash::Shell::GetPrimaryRootWindow(),
-        "org.chromium.arc.testapp.inputoverlay");
+        "org.chromium.arc.testapp.inputoverlay", gfx::Rect(10, 10, 250, 250));
     touch_injector_ = std::make_unique<TouchInjector>(
         arc_test_window_->GetWindow(),
         *arc_test_window_->GetWindow()->GetProperty(ash::kArcPackageNameKey),
diff --git a/chrome/browser/ash/arc/intent_helper/arc_intent_helper_mojo_ash.cc b/chrome/browser/ash/arc/intent_helper/arc_intent_helper_mojo_ash.cc
index 4c55569..2c3c300 100644
--- a/chrome/browser/ash/arc/intent_helper/arc_intent_helper_mojo_ash.cc
+++ b/chrome/browser/ash/arc/intent_helper/arc_intent_helper_mojo_ash.cc
@@ -122,11 +122,8 @@
     RequestTextSelectionActionsCallback callback,
     std::vector<mojom::TextSelectionActionPtr> actions) {
   size_t actions_count = actions.size();
-  if (actions_count == 0) {
-    return;
-  }
   auto converted_actions = std::vector<TextSelectionAction*>(actions_count);
-  TextSelectionAction** converted_actions_ptr = &converted_actions[0];
+  TextSelectionAction** converted_actions_ptr = converted_actions.data();
   base::RepeatingClosure barrier_closure = base::BarrierClosure(
       actions_count, base::BindOnce(
                          [](std::vector<TextSelectionAction*> actions,
diff --git a/chrome/browser/ash/extensions/autotest_private/autotest_private_api.cc b/chrome/browser/ash/extensions/autotest_private/autotest_private_api.cc
index 58543ec..ac64fd10 100644
--- a/chrome/browser/ash/extensions/autotest_private/autotest_private_api.cc
+++ b/chrome/browser/ash/extensions/autotest_private/autotest_private_api.cc
@@ -1030,6 +1030,9 @@
   }
 }
 
+// Update when `startThroughputTrackerDataCollection` is called.
+base::TimeTicks g_last_start_throughput_data_collection_tick;
+
 }  // namespace
 
 class WindowStateChangeObserver : public aura::WindowObserver {
@@ -5921,6 +5924,7 @@
 
 ExtensionFunction::ResponseAction
 AutotestPrivateStartThroughputTrackerDataCollectionFunction::Run() {
+  g_last_start_throughput_data_collection_tick = base::TimeTicks::Now();
   ash::metrics_util::StartDataCollection();
   return RespondNow(NoArguments());
 }
@@ -5943,9 +5947,15 @@
   result_data.reserve(collected_data.size());
   for (const auto& data : collected_data) {
     api::autotest_private::ThroughputTrackerAnimationData animation_data;
-    animation_data.frames_expected = data.frames_expected;
-    animation_data.frames_produced = data.frames_produced;
-    animation_data.jank_count = data.jank_count;
+    animation_data.start_offset_ms =
+        (data.start_tick - g_last_start_throughput_data_collection_tick)
+            .InMilliseconds();
+    animation_data.stop_offset_ms =
+        (data.stop_tick - g_last_start_throughput_data_collection_tick)
+            .InMilliseconds();
+    animation_data.frames_expected = data.smoothness_data.frames_expected;
+    animation_data.frames_produced = data.smoothness_data.frames_produced;
+    animation_data.jank_count = data.smoothness_data.jank_count;
     result_data.emplace_back(std::move(animation_data));
   }
   return RespondNow(
@@ -5970,9 +5980,15 @@
   result_data.reserve(collected_data.size());
   for (const auto& data : collected_data) {
     api::autotest_private::ThroughputTrackerAnimationData animation_data;
-    animation_data.frames_expected = data.frames_expected;
-    animation_data.frames_produced = data.frames_produced;
-    animation_data.jank_count = data.jank_count;
+    animation_data.start_offset_ms =
+        (data.start_tick - g_last_start_throughput_data_collection_tick)
+            .InMilliseconds();
+    animation_data.stop_offset_ms =
+        (data.stop_tick - g_last_start_throughput_data_collection_tick)
+            .InMilliseconds();
+    animation_data.frames_expected = data.smoothness_data.frames_expected;
+    animation_data.frames_produced = data.smoothness_data.frames_produced;
+    animation_data.jank_count = data.smoothness_data.jank_count;
     result_data.emplace_back(std::move(animation_data));
   }
   return RespondNow(ArgumentList(
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_theme_provider_impl.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_theme_provider_impl.cc
index 74db0182..568fd8a 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_theme_provider_impl.cc
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_theme_provider_impl.cc
@@ -171,4 +171,17 @@
   OnStaticColorChanged(static_color);
   OnColorSchemeChanged(color_palette_controller_->color_scheme());
 }
+
+void PersonalizationAppThemeProviderImpl::GenerateSampleColorSchemes(
+    GenerateSampleColorSchemesCallback callback) {
+  const std::vector<ColorScheme> color_scheme_buttons = {
+      ColorScheme::kTonalSpot,
+      ColorScheme::kNeutral,
+      ColorScheme::kVibrant,
+      ColorScheme::kExpressive,
+  };
+  color_palette_controller_->GenerateSampleColorSchemes(color_scheme_buttons,
+                                                        std::move(callback));
+}
+
 }  // namespace ash::personalization_app
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_theme_provider_impl.h b/chrome/browser/ash/web_applications/personalization_app/personalization_app_theme_provider_impl.h
index 1eb6ba1..ebec652 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_theme_provider_impl.h
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_theme_provider_impl.h
@@ -67,6 +67,9 @@
 
   void GetStaticColor(GetStaticColorCallback callback) override;
 
+  void GenerateSampleColorSchemes(
+      GenerateSampleColorSchemesCallback callback) override;
+
  private:
   bool IsColorModeAutoScheduleEnabled();
 
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_theme_provider_impl_unittest.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_theme_provider_impl_unittest.cc
index e60d1d7..a1db18f 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_theme_provider_impl_unittest.cc
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_theme_provider_impl_unittest.cc
@@ -8,8 +8,12 @@
 
 #include "ash/session/session_controller_impl.h"
 #include "ash/shell.h"
+#include "ash/style/color_palette_controller.h"
 #include "ash/style/dark_light_mode_controller_impl.h"
+#include "base/run_loop.h"
+#include "base/test/gmock_callback_support.h"
 #include "base/test/metrics/histogram_tester.h"
+#include "base/test/mock_callback.h"
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/ash/web_applications/personalization_app/personalization_app_metrics.h"
 #include "chrome/test/base/chrome_ash_test_base.h"
@@ -19,6 +23,7 @@
 #include "components/user_manager/scoped_user_manager.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/test_web_ui.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkColor.h"
 
@@ -268,4 +273,33 @@
 
   EXPECT_EQ(color_scheme, GetColorScheme());
 }
+
+TEST_F(PersonalizationAppThemeProviderImplJellyTest,
+       GenerateSampleColorSchemes) {
+  SetThemeObserver();
+  theme_provider_remote()->FlushForTesting();
+  ColorScheme color_scheme_buttons[] = {
+      ColorScheme::kTonalSpot,
+      ColorScheme::kNeutral,
+      ColorScheme::kVibrant,
+      ColorScheme::kExpressive,
+  };
+  std::vector<SampleColorScheme> samples;
+  for (auto scheme : color_scheme_buttons) {
+    samples.push_back({.scheme = scheme,
+                       .primary = SK_ColorRED,
+                       .secondary = SK_ColorGREEN,
+                       .tertiary = SK_ColorBLUE});
+  }
+  base::MockOnceCallback<void(const std::vector<ash::SampleColorScheme>&)>
+      generate_sample_color_schemes_callback;
+  base::RunLoop run_loop;
+  EXPECT_CALL(generate_sample_color_schemes_callback, Run(samples))
+      .WillOnce(base::test::RunClosure(run_loop.QuitClosure()));
+
+  theme_provider()->GenerateSampleColorSchemes(
+      generate_sample_color_schemes_callback.Get());
+  run_loop.Run();
+}
+
 }  // namespace ash::personalization_app
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index d02d110..fd0b8a1 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -243,6 +243,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_features.h"
 #include "components/privacy_sandbox/privacy_sandbox_prefs.h"
 #include "components/privacy_sandbox/privacy_sandbox_settings.h"
 #include "components/safe_browsing/buildflags.h"
@@ -6414,6 +6415,27 @@
                                  chrome::kChromeUIHelpHost);
   }
 
+#if !BUILDFLAG(IS_ANDROID)
+  if (base::FeatureList::IsEnabled(privacy_sandbox::kPrivacySandboxSettings4)) {
+    // Redirect to the new version of privacy sandbox settings.
+    if (url->SchemeIs(content::kChromeUIScheme) &&
+        url->host() == chrome::kChromeUISettingsHost) {
+      if (url->path() == chrome::kPrivacySandboxSubPagePath) {
+        GURL::Replacements replacements;
+        replacements.SetPathStr(chrome::kAdPrivacySubPagePath);
+        *url = url->ReplaceComponents(replacements);
+        UMA_HISTOGRAM_BOOLEAN("Settings.PrivacySandbox.DeprecatedRedirect",
+                              true);
+      } else if (url->path() == chrome::kAdPrivacySubPagePath) {
+        // Log un-redirected navigations to the page as well to provide context
+        // for the raw number of redirects.
+        UMA_HISTOGRAM_BOOLEAN("Settings.PrivacySandbox.DeprecatedRedirect",
+                              false);
+      }
+    }
+  }
+#endif
+
 #if BUILDFLAG(IS_WIN)
   // TODO(crbug.com/1003960): Remove when issue is resolved.
   if (url->SchemeIs(content::kChromeUIScheme) &&
diff --git a/chrome/browser/chrome_content_browser_client_unittest.cc b/chrome/browser/chrome_content_browser_client_unittest.cc
index 4b195a335e..2d18c6a 100644
--- a/chrome/browser/chrome_content_browser_client_unittest.cc
+++ b/chrome/browser/chrome_content_browser_client_unittest.cc
@@ -18,6 +18,7 @@
 #include "base/strings/strcat.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/gtest_util.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/values.h"
 #include "build/build_config.h"
@@ -37,6 +38,7 @@
 #include "components/captive_portal/core/buildflags.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
 #include "components/policy/core/common/policy_pref_names.h"
+#include "components/privacy_sandbox/privacy_sandbox_features.h"
 #include "components/search_engines/template_url_service.h"
 #include "components/services/storage/public/cpp/storage_prefs.h"
 #include "components/variations/variations_associated_data.h"
@@ -517,6 +519,36 @@
                                                              &profile_));
 }
 
+#if !BUILDFLAG(IS_ANDROID)
+TEST_F(ChromeContentBrowserClientTest, RedirectPrivacySandboxURL) {
+  base::test::ScopedFeatureList feature_list(
+      privacy_sandbox::kPrivacySandboxSettings4);
+
+  TestChromeContentBrowserClient test_content_browser_client;
+  base::HistogramTester histogram_tester;
+  const std::string histogram_name =
+      "Settings.PrivacySandbox.DeprecatedRedirect";
+
+  GURL settings_url = GURL(chrome::kChromeUISettingsURL);
+  settings_url = net::AppendQueryParameter(settings_url, "foo", "bar");
+
+  GURL::Replacements replacements;
+  replacements.SetPathStr(chrome::kPrivacySandboxSubPagePath);
+  GURL old_settings_url = settings_url.ReplaceComponents(replacements);
+
+  replacements.SetPathStr(chrome::kAdPrivacySubPagePath);
+  GURL new_settings_url = settings_url.ReplaceComponents(replacements);
+
+  test_content_browser_client.HandleWebUI(&old_settings_url, &profile_);
+  EXPECT_EQ(new_settings_url, old_settings_url);
+  histogram_tester.ExpectUniqueSample(histogram_name, true, 1);
+
+  test_content_browser_client.HandleWebUI(&new_settings_url, &profile_);
+  histogram_tester.ExpectBucketCount(histogram_name, false, 1);
+  histogram_tester.ExpectTotalCount(histogram_name, 2);
+}
+#endif
+
 #if BUILDFLAG(IS_CHROMEOS)
 class ChromeContentSettingsRedirectTest
     : public ChromeContentBrowserClientTest {
diff --git a/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceTrackingButtonControllerUnitTest.java b/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceTrackingButtonControllerUnitTest.java
index a082706e..4532ca26 100644
--- a/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceTrackingButtonControllerUnitTest.java
+++ b/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceTrackingButtonControllerUnitTest.java
@@ -26,7 +26,6 @@
 import org.robolectric.Robolectric;
 import org.robolectric.annotation.Config;
 
-import org.chromium.base.FeatureList;
 import org.chromium.base.supplier.ObservableSupplier;
 import org.chromium.base.supplier.Supplier;
 import org.chromium.base.test.BaseRobolectricTestRunner;
@@ -83,38 +82,6 @@
     }
 
     @Test
-    public void testButtonData_QuietVariation() {
-        PriceTrackingButtonController priceTrackingButtonController =
-                new PriceTrackingButtonController(mMockTabSupplier, mMockModalDialogManager,
-                        mMockBottomSheetController, mock(Drawable.class),
-                        mMockTabBookmarkerSupplier);
-        ButtonData buttonData = priceTrackingButtonController.get(mMockTab);
-
-        // Quiet variation uses an IPHCommandBuilder to highlight the action.
-        Assert.assertNotNull(buttonData.getButtonSpec().getIPHCommandBuilder());
-    }
-
-    @Test
-    public void testButtonData_ActionChipVariation() {
-        FeatureList.TestValues testValues = new FeatureList.TestValues();
-        testValues.addFeatureFlagOverride(ChromeFeatureList.CONTEXTUAL_PAGE_ACTIONS, true);
-        testValues.addFieldTrialParamOverride(
-                ChromeFeatureList.CONTEXTUAL_PAGE_ACTION_PRICE_TRACKING, "action_chip", "true");
-        testValues.addFeatureFlagOverride(
-                ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION_V2, true);
-        FeatureList.setTestValues(testValues);
-
-        PriceTrackingButtonController priceTrackingButtonController =
-                new PriceTrackingButtonController(mMockTabSupplier, mMockModalDialogManager,
-                        mMockBottomSheetController, mock(Drawable.class),
-                        mMockTabBookmarkerSupplier);
-        ButtonData buttonData = priceTrackingButtonController.get(mMockTab);
-
-        // Action chip variation should not set an IPH command builder.
-        Assert.assertNull(buttonData.getButtonSpec().getIPHCommandBuilder());
-    }
-
-    @Test
     public void testPriceTrackingButtonClick() {
         PriceTrackingButtonController priceTrackingButtonController =
                 new PriceTrackingButtonController(mMockTabSupplier, mMockModalDialogManager,
diff --git a/chrome/browser/enterprise/connectors/README.md b/chrome/browser/enterprise/connectors/README.md
index 9b78ad6..3f3b112 100644
--- a/chrome/browser/enterprise/connectors/README.md
+++ b/chrome/browser/enterprise/connectors/README.md
@@ -6,5 +6,4 @@
     * Code shared with user downloads cloud scanning should be added to `//chrome/browser/safe_browsing/cloud_content_scanning/` instead.
     * Code specific to user downloads cloud scanning should be added to `//chrome/browser/safe_browsing/download_protection/` instead.
   * Code specific to reporting Connectors (in reporting/).
-  * Code specific to the file system Connectors (in file_system/).
 
diff --git a/chrome/browser/enterprise/idle/action.cc b/chrome/browser/enterprise/idle/action.cc
index b692d5e7..a6b200e 100644
--- a/chrome/browser/enterprise/idle/action.cc
+++ b/chrome/browser/enterprise/idle/action.cc
@@ -13,19 +13,24 @@
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
 #include "base/ranges/algorithm.h"
+#include "base/scoped_observation.h"
 #include "chrome/browser/browsing_data/chrome_browsing_data_remover_constants.h"
 #include "chrome/browser/enterprise/idle/action_runner.h"
-#include "chrome/browser/enterprise/idle/browser_closer.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/profile_picker.h"
 #include "chrome/common/pref_names.h"
 #include "components/prefs/pref_service.h"
 #include "content/public/browser/browsing_data_remover.h"
 
+#if !BUILDFLAG(IS_ANDROID)
+#include "chrome/browser/enterprise/idle/browser_closer.h"
+#include "chrome/browser/ui/profile_picker.h"
+#endif  // !BUILDFLAG(IS_ANDROID)
+
 namespace enterprise_idle {
 
 namespace {
 
+#if !BUILDFLAG(IS_ANDROID)
 // Wrapper Action for BrowserCloser.
 class CloseBrowsersAction : public Action {
  public:
@@ -66,6 +71,7 @@
     std::move(continuation).Run(true);
   }
 };
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 // Action that clears one or more types of data via BrowsingDataRemover.
 // Multiple data types may be grouped into a single ClearBrowsingDataAction
@@ -183,12 +189,14 @@
   base::flat_set<ActionType> clear_actions;
   for (auto action_type : action_types) {
     switch (action_type) {
+#if !BUILDFLAG(IS_ANDROID)
       case ActionType::kCloseBrowsers:
         actions.push(std::make_unique<CloseBrowsersAction>());
         break;
       case ActionType::kShowProfilePicker:
         actions.push(std::make_unique<ShowProfilePickerAction>());
         break;
+#endif  // !BUILDFLAG(IS_ANDROID)
 
       // "clear_*" actions are all grouped into a single Action object. Collect
       // them in a flat_set<>, and create the shared object once we have the
diff --git a/chrome/browser/enterprise/idle/action.h b/chrome/browser/enterprise/idle/action.h
index c58a8cd1..4069b2dc 100644
--- a/chrome/browser/enterprise/idle/action.h
+++ b/chrome/browser/enterprise/idle/action.h
@@ -12,6 +12,7 @@
 #include "base/containers/span.h"
 #include "base/functional/callback.h"
 #include "base/no_destructor.h"
+#include "build/build_config.h"
 #include "content/public/browser/browsing_data_remover.h"
 
 class Profile;
@@ -23,8 +24,10 @@
 // Actions run in order, based on their numerical value. Lower values run first.
 // Keep this enum sorted by priority.
 enum class ActionType {
+#if !BUILDFLAG(IS_ANDROID)
   kCloseBrowsers = 0,
   kShowProfilePicker = 1,
+#endif  // !BUILDFLAG(IS_ANDROID)
   kClearBrowsingHistory = 2,
   kClearDownloadHistory = 3,
   kClearCookiesAndOtherSiteData = 4,
diff --git a/chrome/browser/enterprise/idle/action_runner_unittest.cc b/chrome/browser/enterprise/idle/action_runner_unittest.cc
index 7ba1f54..e6f5794 100644
--- a/chrome/browser/enterprise/idle/action_runner_unittest.cc
+++ b/chrome/browser/enterprise/idle/action_runner_unittest.cc
@@ -7,6 +7,7 @@
 #include "base/memory/raw_ptr.h"
 #include "base/test/gmock_callback_support.h"
 #include "base/test/mock_callback.h"
+#include "build/build_config.h"
 #include "chrome/browser/browsing_data/chrome_browsing_data_remover_constants.h"
 #include "chrome/browser/enterprise/idle/action.h"
 #include "chrome/common/pref_names.h"
@@ -72,8 +73,8 @@
 
 }  // namespace
 
-using testing::_;
-
+// TODO(crbug.com/1316551): Enable this when Android supports >1 Action.
+#if !BUILDFLAG(IS_ANDROID)
 // Tests that actions are run in sequence, in order of priority.
 TEST(IdleActionRunnerTest, RunsActionsInSequence) {
   content::BrowserTaskEnvironment task_environment;
@@ -164,6 +165,7 @@
                            std::move(show_profile_picker));
   runner.Run();
 }
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 // Tests that it does nothing when the "IdleTimeoutActions" pref is empty.
 TEST(IdleActionRunnerTest, DoNothingWithEmptyPref) {
@@ -173,21 +175,23 @@
   ActionRunner runner(&profile, &action_factory);
 
   // "IdleTimeoutActions" is deliberately unset.
-  auto close_browsers =
-      std::make_unique<MockAction>(ActionType::kCloseBrowsers);
-  auto show_profile_picker =
-      std::make_unique<MockAction>(ActionType::kShowProfilePicker);
+  auto clear_browsing_history =
+      std::make_unique<MockAction>(ActionType::kClearBrowsingHistory);
+  auto clear_download_history =
+      std::make_unique<MockAction>(ActionType::kClearDownloadHistory);
 
-  EXPECT_CALL(*close_browsers, Run(_, _)).Times(0);
-  EXPECT_CALL(*show_profile_picker, Run(_, _)).Times(0);
+  EXPECT_CALL(*clear_browsing_history, Run(_, _)).Times(0);
+  EXPECT_CALL(*clear_download_history, Run(_, _)).Times(0);
 
-  action_factory.Associate(ActionType::kCloseBrowsers,
-                           std::move(close_browsers));
-  action_factory.Associate(ActionType::kShowProfilePicker,
-                           std::move(show_profile_picker));
+  action_factory.Associate(ActionType::kClearBrowsingHistory,
+                           std::move(clear_browsing_history));
+  action_factory.Associate(ActionType::kClearDownloadHistory,
+                           std::move(clear_download_history));
   runner.Run();
 }
 
+// TODO(crbug.com/1316551): Enable this when Android supports >1 Action.
+#if !BUILDFLAG(IS_ANDROID)
 // Tests that ActionRunner only runs the actions configured via the
 // "IdleTimeoutActions" pref.
 TEST(IdleActionRunnerTest, JustCloseBrowsers) {
@@ -243,6 +247,7 @@
                            std::move(show_profile_picker));
   runner.Run();
 }
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 // A basic implementation of BrowsingDataRemover, that doesn't remove any data.
 //
diff --git a/chrome/browser/enterprise/idle/action_unittest.cc b/chrome/browser/enterprise/idle/action_unittest.cc
index b91cd942..99d997b 100644
--- a/chrome/browser/enterprise/idle/action_unittest.cc
+++ b/chrome/browser/enterprise/idle/action_unittest.cc
@@ -9,6 +9,8 @@
 
 namespace enterprise_idle {
 
+// TODO(crbug.com/1316551): Enable this when Android supports >1 Action.
+#if !BUILDFLAG(IS_ANDROID)
 TEST(IdleActionTest, Build) {
   auto* factory = ActionFactory::GetInstance();
 
@@ -23,6 +25,7 @@
   EXPECT_EQ(1u, queue.size());
   EXPECT_EQ(0u, queue.top()->priority());
 }
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 TEST(IdleActionTest, ClearBrowsingDataIsSingleAction) {
   auto* factory = ActionFactory::GetInstance();
diff --git a/chrome/browser/enterprise/idle/idle_service.cc b/chrome/browser/enterprise/idle/idle_service.cc
index ad5e48a..5de4ed2 100644
--- a/chrome/browser/enterprise/idle/idle_service.cc
+++ b/chrome/browser/enterprise/idle/idle_service.cc
@@ -8,6 +8,7 @@
 
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
+#include "base/json/values_util.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/pref_names.h"
 #include "components/prefs/pref_service.h"
diff --git a/chrome/browser/enterprise/idle/idle_timeout_policy_handler.cc b/chrome/browser/enterprise/idle/idle_timeout_policy_handler.cc
index 2a09d51..3fa7afba 100644
--- a/chrome/browser/enterprise/idle/idle_timeout_policy_handler.cc
+++ b/chrome/browser/enterprise/idle/idle_timeout_policy_handler.cc
@@ -38,6 +38,42 @@
   return false;
 }
 
+absl::optional<ActionType> NameToActionType(const std::string& name) {
+#if !BUILDFLAG(IS_ANDROID)
+  if (name == "close_browsers") {
+    return ActionType::kCloseBrowsers;
+  }
+  if (name == "show_profile_picker") {
+    return ActionType::kShowProfilePicker;
+  }
+#endif  // !BUILDFLAG(IS_ANDROID)
+  if (name == "clear_browsing_history") {
+    return ActionType::kClearBrowsingHistory;
+  }
+  if (name == "clear_download_history") {
+    return ActionType::kClearDownloadHistory;
+  }
+  if (name == "clear_cookies_and_other_site_data") {
+    return ActionType::kClearCookiesAndOtherSiteData;
+  }
+  if (name == "clear_cached_images_and_files") {
+    return ActionType::kClearCachedImagesAndFiles;
+  }
+  if (name == "clear_password_signin") {
+    return ActionType::kClearPasswordSignin;
+  }
+  if (name == "clear_autofill") {
+    return ActionType::kClearAutofill;
+  }
+  if (name == "clear_site_settings") {
+    return ActionType::kClearSiteSettings;
+  }
+  if (name == "clear_hosted_app_data") {
+    return ActionType::kClearHostedAppData;
+  }
+  return absl::nullopt;
+}
+
 }  // namespace
 
 IdleTimeoutPolicyHandler::IdleTimeoutPolicyHandler()
@@ -100,33 +136,11 @@
   // Convert strings to integers (from the ActionType enum).
   base::Value::List converted_actions;
   for (const base::Value& action : policy_value->GetList()) {
-    if (!action.is_string())
+    if (!action.is_string()) {
       continue;
-    const std::string& name = action.GetString();
-    absl::optional<ActionType> action_type = absl::nullopt;
-    if (name == "close_browsers") {
-      action_type = ActionType::kCloseBrowsers;
-    } else if (name == "show_profile_picker") {
-      action_type = ActionType::kShowProfilePicker;
-    } else if (name == "clear_browsing_history") {
-      action_type = ActionType::kClearBrowsingHistory;
-    } else if (name == "clear_download_history") {
-      action_type = ActionType::kClearDownloadHistory;
-    } else if (name == "clear_cookies_and_other_site_data") {
-      action_type = ActionType::kClearCookiesAndOtherSiteData;
-    } else if (name == "clear_cached_images_and_files") {
-      action_type = ActionType::kClearCachedImagesAndFiles;
-    } else if (name == "clear_password_signin") {
-      action_type = ActionType::kClearPasswordSignin;
-    } else if (name == "clear_autofill") {
-      action_type = ActionType::kClearAutofill;
-    } else if (name == "clear_site_settings") {
-      action_type = ActionType::kClearSiteSettings;
-    } else if (name == "clear_hosted_app_data") {
-      action_type = ActionType::kClearHostedAppData;
     }
-    // Silently drop unsupported values.
-    if (action_type.has_value()) {
+    if (absl::optional<ActionType> action_type =
+            NameToActionType(action.GetString())) {
       converted_actions.Append(static_cast<int>(action_type.value()));
     }
   }
diff --git a/chrome/browser/enterprise/idle/idle_timeout_policy_handler_unittest.cc b/chrome/browser/enterprise/idle/idle_timeout_policy_handler_unittest.cc
index 99b88b04b..fa7c627 100644
--- a/chrome/browser/enterprise/idle/idle_timeout_policy_handler_unittest.cc
+++ b/chrome/browser/enterprise/idle/idle_timeout_policy_handler_unittest.cc
@@ -163,7 +163,7 @@
   // IdleTimeoutActions is a list, but one of the elements is not even a string.
   SetPolicyValue(policy::key::kIdleTimeout, base::Value(5));
   base::Value::List list;
-  list.Append("close_browsers");
+  list.Append("clear_browsing_history");
   list.Append(34);
   SetPolicyValue(policy::key::kIdleTimeoutActions,
                  base::Value(std::move(list)));
@@ -180,17 +180,19 @@
   EXPECT_EQ(errors().size(), 1U);
   EXPECT_EQ(errors().begin()->second.message, expected_error);
 
-  // Prefs should not be set.
+  // Prefs should be set.
   const base::Value* pref_value;
   EXPECT_TRUE(prefs().GetValue(prefs::kIdleTimeout, &pref_value));
   EXPECT_TRUE(prefs().GetValue(prefs::kIdleTimeoutActions, &pref_value));
+  EXPECT_THAT(pref_value->GetList(), testing::ElementsAre(static_cast<int>(
+                                         ActionType::kClearBrowsingHistory)));
 }
 
 TEST_F(IdleTimeoutPolicyHandlerTest, ValidConfiguration) {
   SetPolicyValue(policy::key::kIdleTimeout, base::Value(15));
   base::Value::List list;
-  list.Append("close_browsers");
-  list.Append("show_profile_picker");
+  list.Append("clear_browsing_history");
+  list.Append("clear_download_history");
   SetPolicyValue(policy::key::kIdleTimeoutActions,
                  base::Value(std::move(list)));
 
@@ -208,10 +210,10 @@
   EXPECT_TRUE(prefs().GetValue(prefs::kIdleTimeoutActions, &pref_value));
   ASSERT_THAT(pref_value, testing::NotNull());
   EXPECT_TRUE(pref_value->is_list());
-  EXPECT_THAT(
-      pref_value->GetList(),
-      testing::ElementsAre(static_cast<int>(ActionType::kCloseBrowsers),
-                           static_cast<int>(ActionType::kShowProfilePicker)));
+  EXPECT_THAT(pref_value->GetList(),
+              testing::ElementsAre(
+                  static_cast<int>(ActionType::kClearBrowsingHistory),
+                  static_cast<int>(ActionType::kClearDownloadHistory)));
 }
 
 TEST_F(IdleTimeoutPolicyHandlerTest, OneMinuteMinimum) {
@@ -240,8 +242,8 @@
   // as a valid option. Recognized actions are applied, but not the others.
   SetPolicyValue(policy::key::kIdleTimeout, base::Value(5));
   base::Value::List list;
-  list.Append("close_browsers");
-  list.Append("show_profile_picker");
+  list.Append("clear_browsing_history");
+  list.Append("clear_download_history");
   list.Append("added_in_future_version_of_chrome");
   SetPolicyValue(policy::key::kIdleTimeoutActions,
                  base::Value(std::move(list)));
@@ -263,17 +265,19 @@
   EXPECT_TRUE(prefs().GetValue(prefs::kIdleTimeoutActions, &pref_value));
   ASSERT_THAT(pref_value, testing::NotNull());
   EXPECT_TRUE(pref_value->is_list());
-  EXPECT_THAT(
-      pref_value->GetList(),
-      testing::ElementsAre(static_cast<int>(ActionType::kCloseBrowsers),
-                           static_cast<int>(ActionType::kShowProfilePicker)));
+  EXPECT_THAT(pref_value->GetList(),
+              testing::ElementsAre(
+                  static_cast<int>(ActionType::kClearBrowsingHistory),
+                  static_cast<int>(ActionType::kClearDownloadHistory)));
 }
 
 TEST_F(IdleTimeoutPolicyHandlerTest, AllActions) {
   SetPolicyValue(policy::key::kIdleTimeout, base::Value(15));
   base::Value::List list;
+#if !BUILDFLAG(IS_ANDROID)
   list.Append("close_browsers");
   list.Append("show_profile_picker");
+#endif  // !BUILDFLAG(IS_ANDROID)
   list.Append("clear_browsing_history");
   list.Append("clear_download_history");
   list.Append("clear_cookies_and_other_site_data");
@@ -301,8 +305,10 @@
   EXPECT_TRUE(pref_value->is_list());
   EXPECT_THAT(pref_value->GetList(),
               testing::ElementsAre(
+#if !BUILDFLAG(IS_ANDROID)
                   static_cast<int>(ActionType::kCloseBrowsers),
                   static_cast<int>(ActionType::kShowProfilePicker),
+#endif  // !BUILDFLAG(IS_ANDROID)
                   static_cast<int>(ActionType::kClearBrowsingHistory),
                   static_cast<int>(ActionType::kClearDownloadHistory),
                   static_cast<int>(ActionType::kClearCookiesAndOtherSiteData),
diff --git a/chrome/browser/extensions/api/debugger/debugger_api.cc b/chrome/browser/extensions/api/debugger/debugger_api.cc
index 992fd41..3531c89 100644
--- a/chrome/browser/extensions/api/debugger/debugger_api.cc
+++ b/chrome/browser/extensions/api/debugger/debugger_api.cc
@@ -740,7 +740,7 @@
 }
 
 void DebuggerSendCommandFunction::SendResponseBody(base::Value response) {
-  if (base::Value* error_body = response.FindKey("error")) {
+  if (base::Value* error_body = response.GetDict().Find("error")) {
     std::string error;
     base::JSONWriter::Write(*error_body, &error);
     Respond(Error(std::move(error)));
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
index cc8f1c3..4cd03a66 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -595,6 +595,8 @@
     public static final CachedFlag sFoldableJankFix = new CachedFlag(FOLDABLE_JANK_FIX, true);
     public static final CachedFlag sGridTabSwitcherForTablets =
             new CachedFlag(GRID_TAB_SWITCHER_FOR_TABLETS, true);
+    public static final CachedFlag sHideNonDisplayableAccountEmail =
+            new CachedFlag(HIDE_NON_DISPLAYABLE_ACCOUNT_EMAIL, false);
     public static final CachedFlag sIncognitoReauthenticationForAndroid =
             new CachedFlag(INCOGNITO_REAUTHENTICATION_FOR_ANDROID, false);
     public static final CachedFlag sInstanceSwitcher = new CachedFlag(INSTANCE_SWITCHER, true);
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc b/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc
index 5e82b1d..a656efe 100644
--- a/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc
+++ b/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc
@@ -88,7 +88,6 @@
   IssueInfo issue_info;
   issue_info.title = title;
   issue_info.message = std::string("msg");
-  issue_info.default_action = IssueInfo::Action::DISMISS;
   issue_info.severity = IssueInfo::Severity::WARNING;
   return issue_info;
 }
diff --git a/chrome/browser/media/router/providers/cast/cast_activity_manager.cc b/chrome/browser/media/router/providers/cast/cast_activity_manager.cc
index 93d0aa6a..c0495d4 100644
--- a/chrome/browser/media/router/providers/cast/cast_activity_manager.cc
+++ b/chrome/browser/media/router/providers/cast/cast_activity_manager.cc
@@ -1006,8 +1006,7 @@
     const MediaRoute::Id& route_id) {
   std::string issue_title =
       l10n_util::GetStringUTF8(IDS_MEDIA_ROUTER_ISSUE_FAILED_TO_CAST);
-  IssueInfo info(issue_title, IssueInfo::Action::DISMISS,
-                 IssueInfo::Severity::WARNING);
+  IssueInfo info(issue_title, IssueInfo::Severity::WARNING);
 
   info.sink_id = sink_id;
   info.route_id = route_id;
@@ -1021,8 +1020,7 @@
       IDS_MEDIA_ROUTER_ISSUE_CREATE_ROUTE_USER_PENDING_AUTHORIZATION,
       base::UTF8ToUTF16(sink_name));
 
-  IssueInfo info(issue_title, IssueInfo::Action::DISMISS,
-                 IssueInfo::Severity::NOTIFICATION);
+  IssueInfo info(issue_title, IssueInfo::Severity::NOTIFICATION);
   info.sink_id = sink_id;
   media_router_->OnIssue(info);
 }
diff --git a/chrome/browser/media/webrtc/capture_policy_utils.cc b/chrome/browser/media/webrtc/capture_policy_utils.cc
index 0911da6..f3f4d45 100644
--- a/chrome/browser/media/webrtc/capture_policy_utils.cc
+++ b/chrome/browser/media/webrtc/capture_policy_utils.cc
@@ -107,7 +107,7 @@
 
 bool IsGetDisplayMediaSetSelectAllScreensAllowedForAnySite(
     content::BrowserContext* context) {
-#if BUILDFLAG(IS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
   Profile* profile = Profile::FromBrowserContext(context);
   if (!profile) {
     return false;
@@ -134,7 +134,7 @@
 bool IsGetDisplayMediaSetSelectAllScreensAllowed(
     content::BrowserContext* context,
     const GURL& url) {
-#if BUILDFLAG(IS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
   Profile* profile = Profile::FromBrowserContext(context);
   if (!profile)
     return false;
@@ -148,7 +148,7 @@
           ContentSettingsType::GET_DISPLAY_MEDIA_SET_SELECT_ALL_SCREENS);
   return auto_accept_enabled == ContentSetting::CONTENT_SETTING_ALLOW;
 #else
-  // This API is currently only available on ChromeOS.
+  // This API is currently only available on ChromeOS and Linux.
   return false;
 #endif
 }
diff --git a/chrome/browser/net/private_network_access_browsertest.cc b/chrome/browser/net/private_network_access_browsertest.cc
index ab7766627..2a0e306e 100644
--- a/chrome/browser/net/private_network_access_browsertest.cc
+++ b/chrome/browser/net/private_network_access_browsertest.cc
@@ -173,6 +173,8 @@
       WebFeature::kAddressSpaceUnknownNonSecureContextNavigatedToPrivate,
       WebFeature::kPrivateNetworkAccessIgnoredPreflightError,
       WebFeature::kPrivateNetworkAccessFetchedWorkerScript,
+      WebFeature::kPrivateNetworkAccessFetchedSubFrame,
+      WebFeature::kPrivateNetworkAccessFetchedTopFrame,
       WebFeature::kPrivateNetworkAccessWithinWorker,
   };
 }
@@ -508,6 +510,7 @@
       AllZeroFeatureCounts(AllAddressSpaceFeatures()),
       {
           {WebFeature::kAddressSpacePublicNonSecureContextNavigatedToLocal, 1},
+          {WebFeature::kPrivateNetworkAccessFetchedTopFrame, 1},
       }));
 }
 
@@ -539,6 +542,7 @@
       AllZeroFeatureCounts(AllAddressSpaceFeatures()),
       {
           {WebFeature::kAddressSpacePublicNonSecureContextNavigatedToLocal, 1},
+          {WebFeature::kPrivateNetworkAccessFetchedTopFrame, 1},
       }));
 }
 
@@ -598,6 +602,7 @@
       AllZeroFeatureCounts(AllAddressSpaceFeatures()),
       {
           {WebFeature::kAddressSpacePublicNonSecureContextNavigatedToLocal, 1},
+          {WebFeature::kPrivateNetworkAccessFetchedSubFrame, 1},
       }));
 }
 
@@ -639,6 +644,7 @@
       AllZeroFeatureCounts(AllAddressSpaceFeatures()),
       {
           {WebFeature::kAddressSpacePublicNonSecureContextNavigatedToLocal, 1},
+          {WebFeature::kPrivateNetworkAccessFetchedSubFrame, 1},
       }));
 }
 
@@ -670,6 +676,7 @@
       AllZeroFeatureCounts(AllAddressSpaceFeatures()),
       {
           {WebFeature::kAddressSpacePublicNonSecureContextNavigatedToLocal, 1},
+          {WebFeature::kPrivateNetworkAccessFetchedSubFrame, 1},
       }));
 }
 
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
index 33a4ee8d..adfd3f5 100644
--- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -1637,9 +1637,6 @@
   { key::kDevicePolicyRefreshRate,
     prefs::kDevicePolicyRefreshRate,
     base::Value::Type::INTEGER },
-  { key::kGetDisplayMediaSetSelectAllScreensAllowedForUrls,
-    prefs::kManagedGetDisplayMediaSetSelectAllScreensAllowedForUrls,
-    base::Value::Type::LIST },
   { key::kLacrosSecondaryProfilesAllowed,
     prefs::kLacrosSecondaryProfilesAllowed,
     base::Value::Type::BOOLEAN },
@@ -1678,6 +1675,12 @@
     base::Value::Type::BOOLEAN },
 #endif // BUILDFLAG(IS_CHROMEOS)
 
+#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
+  { key::kGetDisplayMediaSetSelectAllScreensAllowedForUrls,
+    prefs::kManagedGetDisplayMediaSetSelectAllScreensAllowedForUrls,
+    base::Value::Type::LIST },
+#endif  // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
+
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS)
   { key::kAuthNegotiateDelegateByKdcPolicy,
     prefs::kAuthNegotiateDelegateByKdcPolicy,
@@ -2035,14 +2038,6 @@
       SimpleSchemaValidatingPolicyHandler::RECOMMENDED_PROHIBITED,
       SimpleSchemaValidatingPolicyHandler::MANDATORY_ALLOWED));
 
-#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
-  handlers->AddHandler(
-      std::make_unique<enterprise_idle::IdleTimeoutPolicyHandler>());
-  handlers->AddHandler(
-      std::make_unique<enterprise_idle::IdleTimeoutActionsPolicyHandler>(
-          chrome_schema));
-#endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
-
   handlers->AddHandler(std::make_unique<RestoreOnStartupPolicyHandler>());
   handlers->AddHandler(std::make_unique<SimpleSchemaValidatingPolicyHandler>(
       key::kSerialAllowUsbDevicesForUrls,
@@ -2063,6 +2058,16 @@
       prefs::kManagedWebHidAllowDevicesWithHidUsagesForUrls, chrome_schema));
 #endif
 
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
+    BUILDFLAG(IS_ANDROID)
+  handlers->AddHandler(
+      std::make_unique<enterprise_idle::IdleTimeoutPolicyHandler>());
+  handlers->AddHandler(
+      std::make_unique<enterprise_idle::IdleTimeoutActionsPolicyHandler>(
+          chrome_schema));
+#endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
+        // BUILDFLAG(IS_ANDROID)
+
   handlers->AddHandler(
       std::make_unique<content_settings::CookieSettingsPolicyHandler>());
   handlers->AddHandler(
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_service.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_service.cc
index aead0ac..08473ff6 100644
--- a/chrome/browser/privacy_sandbox/privacy_sandbox_service.cc
+++ b/chrome/browser/privacy_sandbox/privacy_sandbox_service.cc
@@ -1156,6 +1156,16 @@
           "Settings.PrivacySandbox.Notice.LearnMoreClosed"));
       break;
     }
+    case (PromptAction::kConsentMoreButtonClicked): {
+      base::RecordAction(base::UserMetricsAction(
+          "Settings.PrivacySandbox.Consent.MoreButtonClicked"));
+      break;
+    }
+    case (PromptAction::kNoticeMoreButtonClicked): {
+      base::RecordAction(base::UserMetricsAction(
+          "Settings.PrivacySandbox.Notice.MoreButtonClicked"));
+      break;
+    }
   }
 }
 
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_service.h b/chrome/browser/privacy_sandbox/privacy_sandbox_service.h
index 74ef213..ee9ddb4 100644
--- a/chrome/browser/privacy_sandbox/privacy_sandbox_service.h
+++ b/chrome/browser/privacy_sandbox/privacy_sandbox_service.h
@@ -92,7 +92,11 @@
     kNoticeMoreInfoOpened = 12,
     kNoticeMoreInfoClosed = 13,
 
-    kMaxValue = kNoticeMoreInfoClosed,
+    // The button is shown only when the prompt content isn't fully visible.
+    kConsentMoreButtonClicked = 14,
+    kNoticeMoreButtonClicked = 15,
+
+    kMaxValue = kNoticeMoreButtonClicked,
   };
 
   // TODO(crbug.com/1378703): Integrate this when handling Notice and Consent
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_service_unittest.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_service_unittest.cc
index 9ec52d9..016ec38 100644
--- a/chrome/browser/privacy_sandbox/privacy_sandbox_service_unittest.cc
+++ b/chrome/browser/privacy_sandbox/privacy_sandbox_service_unittest.cc
@@ -27,9 +27,10 @@
 #include "components/content_settings/core/test/content_settings_test_utils.h"
 #include "components/policy/core/common/mock_policy_service.h"
 #include "components/privacy_sandbox/canonical_topic.h"
+#include "components/privacy_sandbox/mock_privacy_sandbox_settings.h"
 #include "components/privacy_sandbox/privacy_sandbox_features.h"
 #include "components/privacy_sandbox/privacy_sandbox_prefs.h"
-#include "components/privacy_sandbox/privacy_sandbox_settings.h"
+#include "components/privacy_sandbox/privacy_sandbox_settings_impl.h"
 #include "components/privacy_sandbox/privacy_sandbox_test_util.h"
 #include "components/profile_metrics/browser_profile_type.h"
 #include "components/signin/public/identity_manager/account_info.h"
@@ -177,17 +178,6 @@
   std::vector<InterestGroupDataKey> data_keys_;
 };
 
-class MockPrivacySandboxSettings
-    : public privacy_sandbox::PrivacySandboxSettings {
- public:
-  void SetUpDefaultResponse() {
-    ON_CALL(*this, IsPrivacySandboxRestricted).WillByDefault([]() {
-      return false;
-    });
-  }
-  MOCK_METHOD(bool, IsPrivacySandboxRestricted, (), (const, override));
-};
-
 struct PromptTestState {
   bool consent_required;
   bool old_api_pref;
@@ -895,7 +885,7 @@
         /*restricted=*/false);
 
     privacy_sandbox_settings_ =
-        std::make_unique<privacy_sandbox::PrivacySandboxSettings>(
+        std::make_unique<privacy_sandbox::PrivacySandboxSettingsImpl>(
             std::move(mock_delegate), host_content_settings_map(),
             cookie_settings(), prefs());
 #if !BUILDFLAG(IS_ANDROID)
@@ -1229,6 +1219,16 @@
       PrivacySandboxService::PromptAction::kNoticeMoreInfoClosed);
   EXPECT_EQ(1, user_action_tester.GetActionCount(
                    "Settings.PrivacySandbox.Notice.LearnMoreClosed"));
+
+  privacy_sandbox_service()->PromptActionOccurred(
+      PrivacySandboxService::PromptAction::kConsentMoreButtonClicked);
+  EXPECT_EQ(1, user_action_tester.GetActionCount(
+                   "Settings.PrivacySandbox.Consent.MoreButtonClicked"));
+
+  privacy_sandbox_service()->PromptActionOccurred(
+      PrivacySandboxService::PromptAction::kNoticeMoreButtonClicked);
+  EXPECT_EQ(1, user_action_tester.GetActionCount(
+                   "Settings.PrivacySandbox.Notice.MoreButtonClicked"));
 }
 
 #if !BUILDFLAG(IS_ANDROID)
@@ -2861,7 +2861,8 @@
   sync_preferences::TestingPrefServiceSyncable* prefs() {
     return &pref_service_;
   }
-  MockPrivacySandboxSettings* privacy_sandbox_settings() {
+  privacy_sandbox_test_util::MockPrivacySandboxSettings*
+  privacy_sandbox_settings() {
     return &privacy_sandbox_settings_;
   }
 
@@ -2871,7 +2872,8 @@
   std::unique_ptr<ash::FakeChromeUserManager> user_manager_;
 #endif
   sync_preferences::TestingPrefServiceSyncable pref_service_;
-  MockPrivacySandboxSettings privacy_sandbox_settings_;
+  privacy_sandbox_test_util::MockPrivacySandboxSettings
+      privacy_sandbox_settings_;
 };
 
 class PrivacySandboxServicePromptTest
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_factory.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_factory.cc
index 0f396c4..2cbfdacdb 100644
--- a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_factory.cc
+++ b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_factory.cc
@@ -11,7 +11,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "components/content_settings/core/browser/cookie_settings.h"
 #include "components/keyed_service/core/keyed_service.h"
-#include "components/privacy_sandbox/privacy_sandbox_settings.h"
+#include "components/privacy_sandbox/privacy_sandbox_settings_impl.h"
 
 PrivacySandboxSettingsFactory* PrivacySandboxSettingsFactory::GetInstance() {
   return base::Singleton<PrivacySandboxSettingsFactory>::get();
@@ -41,7 +41,7 @@
     content::BrowserContext* context) const {
   Profile* profile = Profile::FromBrowserContext(context);
 
-  return new privacy_sandbox::PrivacySandboxSettings(
+  return new privacy_sandbox::PrivacySandboxSettingsImpl(
       std::make_unique<PrivacySandboxSettingsDelegate>(profile),
       HostContentSettingsMapFactory::GetForProfile(profile),
       CookieSettingsFactory::GetForProfile(profile).get(), profile->GetPrefs());
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
index 0bd51d1..8826b05 100644
--- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
+++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -260,7 +260,8 @@
 #include "chrome/browser/ui/cocoa/screentime/screentime_features.h"
 #endif
 
-#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
+    BUILDFLAG(IS_ANDROID)
 #include "chrome/browser/enterprise/idle/idle_service_factory.h"
 #endif
 
@@ -448,7 +449,8 @@
     (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
   metrics::DesktopProfileSessionDurationsServiceFactory::GetInstance();
 #endif
-#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
+    BUILDFLAG(IS_ANDROID)
   enterprise_idle::IdleServiceFactory::GetInstance();
 #endif
   ModelTypeStoreServiceFactory::GetInstance();
diff --git a/chrome/browser/resources/bookmarks/BUILD.gn b/chrome/browser/resources/bookmarks/BUILD.gn
index 30fcfd0a..37a4400e 100644
--- a/chrome/browser/resources/bookmarks/BUILD.gn
+++ b/chrome/browser/resources/bookmarks/BUILD.gn
@@ -26,6 +26,7 @@
     "bookmarks.ts",
     "api_listener.ts",
     "bookmarks_api_proxy.ts",
+    "bookmark_manager_api_proxy.ts",
     "browser_proxy.ts",
     "constants.ts",
     "debouncer.ts",
diff --git a/chrome/browser/resources/bookmarks/bookmark_manager_api_proxy.ts b/chrome/browser/resources/bookmarks/bookmark_manager_api_proxy.ts
new file mode 100644
index 0000000..b291cd93
--- /dev/null
+++ b/chrome/browser/resources/bookmarks/bookmark_manager_api_proxy.ts
@@ -0,0 +1,44 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+import {ChromeEvent} from '/tools/typescript/definitions/chrome_event.js';
+
+export interface BookmarkManagerApiProxy {
+  onDragEnter:
+      ChromeEvent<(p1: chrome.bookmarkManagerPrivate.DragData) => void>;
+
+  drop(parentId: string, index?: number): Promise<void>;
+  startDrag(
+      idList: string[], dragNodeIndex: number, isFromTouch: boolean, x: number,
+      y: number): void;
+  removeTrees(idList: string[]): Promise<void>;
+}
+
+export class BookmarkManagerApiProxyImpl implements BookmarkManagerApiProxy {
+  onDragEnter = chrome.bookmarkManagerPrivate.onDragEnter;
+
+  drop(parentId: string, index?: number) {
+    return chrome.bookmarkManagerPrivate.drop(parentId, index);
+  }
+
+  startDrag(
+      idList: string[], dragNodeIndex: number, isFromTouch: boolean, x: number,
+      y: number) {
+    return chrome.bookmarkManagerPrivate.startDrag(
+        idList, dragNodeIndex, isFromTouch, x, y);
+  }
+
+  removeTrees(idList: string[]) {
+    return chrome.bookmarkManagerPrivate.removeTrees(idList);
+  }
+
+  static getInstance(): BookmarkManagerApiProxy {
+    return instance || (instance = new BookmarkManagerApiProxyImpl());
+  }
+
+  static setInstance(obj: BookmarkManagerApiProxy) {
+    instance = obj;
+  }
+}
+
+let instance: BookmarkManagerApiProxy|null = null;
diff --git a/chrome/browser/resources/bookmarks/bookmarks.ts b/chrome/browser/resources/bookmarks/bookmarks.ts
index 1e85e1d..d810bf4f 100644
--- a/chrome/browser/resources/bookmarks/bookmarks.ts
+++ b/chrome/browser/resources/bookmarks/bookmarks.ts
@@ -7,12 +7,13 @@
 export {changeFolderOpen, clearSearch, createBookmark, deselectItems, editBookmark, moveBookmark, removeBookmark, reorderChildren, selectFolder, SelectFolderAction, selectItem, SelectItemsAction, setSearchResults, setSearchTerm, StartSearchAction, updateAnchor} from './actions.js';
 export {setDebouncerForTesting} from './api_listener.js';
 export {BookmarksAppElement} from './app.js';
+export {BookmarkManagerApiProxy, BookmarkManagerApiProxyImpl} from './bookmark_manager_api_proxy.js';
 export {BookmarksApiProxy, BookmarksApiProxyImpl, Query} from './bookmarks_api_proxy.js';
 export {BrowserProxy, BrowserProxyImpl} from './browser_proxy.js';
 export {BookmarksCommandManagerElement} from './command_manager.js';
 export {Command, DropPosition, IncognitoAvailability, LOCAL_STORAGE_FOLDER_STATE_KEY, LOCAL_STORAGE_TREE_WIDTH_KEY, MenuSource, ROOT_NODE_ID} from './constants.js';
 export {DialogFocusManager} from './dialog_focus_manager.js';
-export {DragInfo} from './dnd_manager.js';
+export {DndManager, DragInfo} from './dnd_manager.js';
 export {BookmarksEditDialogElement} from './edit_dialog.js';
 export {BookmarksFolderNodeElement} from './folder_node.js';
 export {BookmarksItemElement} from './item.js';
@@ -22,5 +23,5 @@
 export {Store} from './store.js';
 export {StoreClientMixin} from './store_client_mixin.js';
 export {BookmarksToolbarElement} from './toolbar.js';
-export {BookmarkNode, BookmarksPageState, FolderOpenState, NodeMap, SelectionState} from './types.js';
+export {BookmarkElement, BookmarkNode, BookmarksPageState, FolderOpenState, NodeMap, SelectionState} from './types.js';
 export {canEditNode, canReorderChildren, createEmptyState, getDescendants, getDisplayedList, isShowingSearch, normalizeNode, normalizeNodes, removeIdsFromObject, removeIdsFromSet} from './util.js';
diff --git a/chrome/browser/resources/bookmarks/command_manager.ts b/chrome/browser/resources/bookmarks/command_manager.ts
index 90fd607..cadd355 100644
--- a/chrome/browser/resources/bookmarks/command_manager.ts
+++ b/chrome/browser/resources/bookmarks/command_manager.ts
@@ -21,16 +21,17 @@
 import {CrLazyRenderElement} from 'chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.js';
 import {getToastManager} from 'chrome://resources/cr_elements/cr_toast/cr_toast_manager.js';
 import {assert, assertNotReached} from 'chrome://resources/js/assert_ts.js';
-import {isMac} from 'chrome://resources/js/platform.js';
-import {KeyboardShortcutList} from 'chrome://resources/js/keyboard_shortcut_list.js';
 import {EventTracker} from 'chrome://resources/js/event_tracker.js';
+import {KeyboardShortcutList} from 'chrome://resources/js/keyboard_shortcut_list.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
+import {isMac} from 'chrome://resources/js/platform.js';
 import {PluralStringProxyImpl} from 'chrome://resources/js/plural_string_proxy.js';
 import {IronA11yAnnouncer} from 'chrome://resources/polymer/v3_0/iron-a11y-announcer/iron-a11y-announcer.js';
 import {afterNextRender, flush, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {deselectItems, selectAll, selectFolder} from './actions.js';
 import {highlightUpdatedItems, trackUpdatedItems} from './api_listener.js';
+import {BookmarkManagerApiProxyImpl} from './bookmark_manager_api_proxy.js';
 import {BrowserProxy, BrowserProxyImpl} from './browser_proxy.js';
 import {getTemplate} from './command_manager.html.js';
 import {Command, IncognitoAvailability, MenuSource, OPEN_CONFIRMATION_LIMIT, ROOT_NODE_ID} from './constants.js';
@@ -365,9 +366,10 @@
               'toastItemsDeleted', idList.length);
         }
 
-        chrome.bookmarkManagerPrivate.removeTrees(idList).then(() => {
-          this.showTitleToast_(labelPromise, title, true);
-        });
+        BookmarkManagerApiProxyImpl.getInstance().removeTrees(idList).then(
+            () => {
+              this.showTitleToast_(labelPromise, title, true);
+            });
         break;
       }
       case Command.UNDO:
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test_base.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test_base.js
index 6a67411..df7ded4 100644
--- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test_base.js
+++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test_base.js
@@ -374,20 +374,19 @@
    * @return {!Promise}
    */
   async waitForUIProperties(targetProps) {
-    if (this.uiPropertiesMatch_(targetProps)) {
-      return;
-    }
-
-    await new Promise(resolve => {
-      const onUpdateDictationBubble = () => {
+    // Poll until the updateDictationBubble() API gets called with
+    // `targetProps`.
+    return new Promise(resolve => {
+      const printErrorMessageTimeoutId = setTimeout(() => {
+        this.printErrorMessage_(targetProps);
+      }, 3.5 * 1000);
+      const intervalId = setInterval(() => {
         if (this.uiPropertiesMatch_(targetProps)) {
-          this.mockAccessibilityPrivate.removeUpdateDictationBubbleListener();
+          clearTimeout(printErrorMessageTimeoutId);
+          clearInterval(intervalId);
           resolve();
         }
-      };
-
-      this.mockAccessibilityPrivate.addUpdateDictationBubbleListener(
-          onUpdateDictationBubble);
+      }, 100);
     });
   }
 
@@ -428,6 +427,18 @@
   }
 
   /**
+   * @param {DictationBubbleProperties} props
+   * @private
+   */
+  printErrorMessage_(props) {
+    console.error(`Still waiting for UI properties
+      visible: ${props.visible}
+      icon: ${props.icon}
+      text: ${props.text}
+      hints: ${props.hints}`);
+  }
+
+  /**
    * Always allows Dictation commands, even if the Dictation locale and browser
    * locale differ. Only used for testing.
    */
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test_support.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test_support.js
index b1d959da..052d8fe 100644
--- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test_support.js
+++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test_support.js
@@ -30,91 +30,66 @@
     this.notifyCcTests_();
   }
 
-  /** Waits for the FocusHandler to initialize. */
+  /**
+   * TODO(b:264535324): Remove polling from this method.
+   * Waits for the FocusHandler to initialize.
+   */
   async waitForFocusHandler() {
-    const focusHandler = this.dictation_.focusHandler_;
-    const isReady = () => {
-      return focusHandler.isReadyForTesting();
-    };
-
-    if (isReady()) {
-      this.notifyCcTests_();
-      return;
-    }
-
     await new Promise(resolve => {
-      // Wait for focusHandler to be active and have a valid editable node by
-      // attaching the necessary event listeners.
-      const onPropertyChanged = () => {
-        if (isReady()) {
-          focusHandler.onActiveChangedForTesting_ = null;
-          focusHandler.onEditableNodeChangedForTesting_ = null;
+      const printErrorMessageTimeoutId = setTimeout(() => {
+        console.error('Still waiting for FocusHandler');
+      }, 3.5 * 1000);
+      const intervalId = setInterval(() => {
+        if (this.dictation_.focusHandler_.isReadyForTesting()) {
+          clearTimeout(printErrorMessageTimeoutId);
+          clearInterval(intervalId);
           resolve();
         }
-      };
-
-      focusHandler.onActiveChangedForTesting_ = onPropertyChanged;
-      focusHandler.onEditableNodeChangedForTesting_ = onPropertyChanged;
+      }, 500);
     });
 
     this.notifyCcTests_();
   }
 
-  /** Waits for the SandboxedPumpkinTagger to initialize. */
+  /**
+   * TODO(b:264535324): Remove polling from this method.
+   * Waits for the SandboxedPumpkinTagger to initialize.
+   */
   async WaitForPumpkinTaggerReady() {
-    const strategy = this.dictation_.speechParser_.pumpkinParseStrategy_;
-    const isReady = () => {
-      return strategy.pumpkinTaggerReady_;
-    };
-
-    if (isReady()) {
-      this.notifyCcTests_();
-      return;
-    }
-
     await new Promise(resolve => {
-      // Wait for SandboxedPumpkinTagger to initialize by attaching the
-      // necessary event listener.
-      const onPropertyChanged = () => {
-        if (isReady()) {
-          strategy.onPumpkinTaggerReadyChangedForTesting_ = null;
+      const printErrorMessageTimeoutId = setTimeout(() => {
+        console.error('Still waiting for SandboxedPumpkinTagger');
+      }, 3.5 * 1000);
+      const intervalId = setInterval(() => {
+        if (this.dictation_.speechParser_.pumpkinParseStrategy_
+                .pumpkinTaggerReady_) {
+          clearTimeout(printErrorMessageTimeoutId);
+          clearInterval(intervalId);
           resolve();
         }
-      };
-      strategy.onPumpkinTaggerReadyChangedForTesting_ = onPropertyChanged;
+      }, 500);
     });
 
     this.notifyCcTests_();
   }
 
-  /** @param {string} value */
+  /**
+   * TODO(b:264535324): Remove polling from this method.
+   * @param {string} value
+   */
   async waitForEditableValue(value) {
-    const inputController = this.dictation_.inputController_;
-    const goalTest = () => {
-      const data = inputController.getEditableNodeData();
-      return data && data.value === value;
-    };
-
-    if (goalTest()) {
-      this.notifyCcTests_();
-      return;
-    }
-
     await new Promise(resolve => {
-      // Wait for the editable value by attaching the necessary event listener.
-      const editableNode = inputController.getEditableNodeData().node;
-      const onValueChanged = () => {
-        if (goalTest()) {
-          editableNode.removeEventListener(
-              chrome.automation.EventType.VALUE_IN_TEXT_FIELD_CHANGED,
-              onValueChanged, false);
+      const printErrorMessageTimeoutId = setTimeout(() => {
+        console.error('Still waiting for editable value: ' + value);
+      }, 3.5 * 1000);
+      const intervalId = setInterval(() => {
+        const data = this.dictation_.inputController_.getEditableNodeData();
+        if (data && data.value === value) {
+          clearTimeout(printErrorMessageTimeoutId);
+          clearInterval(intervalId);
           resolve();
         }
-      };
-
-      editableNode.addEventListener(
-          chrome.automation.EventType.VALUE_IN_TEXT_FIELD_CHANGED,
-          onValueChanged, false);
+      }, 500);
     });
 
     this.notifyCcTests_();
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/focus_handler.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/focus_handler.js
index 1c34e48..06d00a3 100644
--- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/focus_handler.js
+++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/focus_handler.js
@@ -26,13 +26,6 @@
 
     /** @private {?EventHandler} */
     this.eventHandler_ = null;
-
-    /** @private {?function(): void} */
-    this.onActiveChangedForTesting_ = null;
-    /** @private {?function(): void} */
-    this.onEditableNodeChangedForTesting_ = null;
-    /** @private {?function(): void} */
-    this.onFocusChangedForTesting_ = null;
   }
 
   /**
@@ -63,7 +56,7 @@
     const desktop = await AsyncUtil.getDesktop();
     const focus = await AsyncUtil.getFocus();
     if (focus && AutomationPredicate.editText(focus)) {
-      this.setEditableNode_(focus);
+      this.editableNode_ = focus;
     }
 
     if (!this.eventHandler_) {
@@ -73,15 +66,15 @@
     this.eventHandler_.setNodes(desktop);
     this.eventHandler_.start();
 
-    this.setActive_(true);
+    this.active_ = true;
   }
 
   /** @private */
   deactivate_() {
     this.eventHandler_.stop();
     this.eventHandler_ = null;
-    this.setActive_(false);
-    this.setEditableNode_(null);
+    this.active_ = false;
+    this.editableNode_ = null;
   }
 
   /**
@@ -92,15 +85,11 @@
   onFocusChanged_(event) {
     const node = event.target;
     if (!node || !AutomationPredicate.editText(node)) {
-      this.setEditableNode_(null);
+      this.editableNode_ = null;
       return;
     }
 
-    this.setEditableNode_(node);
-
-    if (this.onFocusChangedForTesting_) {
-      this.onFocusChangedForTesting_();
-    }
+    this.editableNode_ = node;
   }
 
   /** @return {?AutomationNode} */
@@ -108,28 +97,6 @@
     return this.editableNode_;
   }
 
-  /**
-   * @param {boolean} value
-   * @private
-   */
-  setActive_(value) {
-    this.active_ = value;
-    if (this.onActiveChangedForTesting_) {
-      this.onActiveChangedForTesting_();
-    }
-  }
-
-  /**
-   * @param {AutomationNode} node
-   * @private
-   */
-  setEditableNode_(node) {
-    this.editableNode_ = node;
-    if (this.onEditableNodeChangedForTesting_) {
-      this.onEditableNodeChangedForTesting_();
-    }
-  }
-
   /** @return {boolean} */
   isReadyForTesting() {
     return this.active_ && this.editableNode_ !== null;
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/focus_handler_test.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/focus_handler_test.js
index 1d98645..8d19db6 100644
--- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/focus_handler_test.js
+++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/focus_handler_test.js
@@ -29,24 +29,13 @@
    * @return {!Promise}
    */
   async waitForFocusHandlerActive(active) {
-    const focusHandler = this.getFocusHandler();
-    const activeOk = () => {
-      return focusHandler.active_ === active;
-    };
-
-    if (activeOk()) {
-      return;
-    }
-
-    await new Promise(resolve => {
-      const onActiveChanged = () => {
-        if (activeOk()) {
-          focusHandler.onActiveChangedForTesting_ = null;
+    return new Promise(resolve => {
+      const intervalId = setInterval(() => {
+        if (this.getFocusHandler().active_ === active) {
+          clearInterval(intervalId);
           resolve();
         }
-      };
-
-      focusHandler.onActiveChangedForTesting_ = onActiveChanged;
+      }, 100);
     });
   }
 
@@ -55,24 +44,13 @@
    * @return {!Promise}
    */
   async waitForFocus(target) {
-    const focusHandler = this.getFocusHandler();
-    const isTargetFocused = () => {
-      return focusHandler.editableNode_ === target;
-    };
-
-    if (isTargetFocused()) {
-      return;
-    }
-
-    await new Promise(resolve => {
-      const onFocusChanged = () => {
-        if (isTargetFocused()) {
-          focusHandler.onFocusChangedForTesting_ = null;
+    return new Promise(resolve => {
+      const intervalId = setInterval(() => {
+        if (this.getFocusHandler().editableNode_ === target) {
+          clearInterval(intervalId);
           resolve();
         }
-      };
-
-      focusHandler.onFocusChangedForTesting_ = onFocusChanged;
+      }, 100);
     });
   }
 
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/parse/dictation_pumpkin_parse_test.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/parse/dictation_pumpkin_parse_test.js
index a37a63d..7e675ca 100644
--- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/parse/dictation_pumpkin_parse_test.js
+++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/parse/dictation_pumpkin_parse_test.js
@@ -19,9 +19,6 @@
     await importModule(
         'SpeechParser',
         '/accessibility_common/dictation/parse/speech_parser.js');
-    await importModule(
-        'SUPPORTED_LOCALES',
-        '/accessibility_common/dictation/parse/pumpkin/pumpkin_constants.js');
 
     await super.setUpDeferred();
 
@@ -32,35 +29,19 @@
 
   /**
    * @return {!Promise}
-   * @param {string=} locale An optional locale. If the locale is provided,
-   * this method will wait for Pumpkin to initialize in that locale. If the
-   * locale isn't provided, then this method will wait for Pumpkin to
-   * initialize in any locale.
    * @private
    */
-  async waitForPumpkinParseStrategy_(locale) {
+  async waitForPumpkinParseStrategy_() {
     const strategy = this.getPumpkinParseStrategy();
-    const isReady = () => {
-      let localeOk = true;
-      if (locale) {
-        const pumpkinLocale = SUPPORTED_LOCALES[locale] || null;
-        localeOk = pumpkinLocale === strategy.locale_;
-      }
-
-      return localeOk && strategy.pumpkinTaggerReady_;
-    };
-
-    if (isReady()) {
-      return;
-    }
-
-    await new Promise(resolve => {
-      strategy.onPumpkinTaggerReadyChangedForTesting_ = () => {
-        if (isReady()) {
-          strategy.onPumpkinTaggerReadyChangedForTesting_ = null;
+    // TODO(crbug.com/1258190): Consider adding an observer or callback and
+    // remove the polling below.
+    return new Promise(resolve => {
+      const intervalId = setInterval(() => {
+        if (strategy.pumpkinTaggerReady_) {
+          clearInterval(intervalId);
           resolve();
         }
-      };
+      }, 300);
     });
   }
 };
@@ -218,7 +199,7 @@
   ];
   for (const {locale, testCase} of testCases) {
     await this.setPref(Dictation.DICTATION_LOCALE_PREF, locale);
-    await this.waitForPumpkinParseStrategy_(locale);
+    await this.waitForPumpkinParseStrategy_();
     await this.runPumpkinParseTestCase(testCase);
   }
 });
@@ -227,15 +208,13 @@
   await this.waitForPumpkinParseStrategy_();
   this.alwaysEnableCommands();
   await this.setPref(Dictation.DICTATION_LOCALE_PREF, 'ja');
-  // Don't pass in a locale below because 'ja' is an unsupported locale (and
-  // thus Pumpkin will never initialize in that locale).
   await this.waitForPumpkinParseStrategy_();
   await this.runPumpkinParseTestCase(
       new ParseTestCase('copy selected text', {}));
   // Would produce an UNDO_TEXT_EDIT macro if Japanese was supported.
   await this.runPumpkinParseTestCase(new ParseTestCase('もとどおりにする', {}));
   await this.setPref(Dictation.DICTATION_LOCALE_PREF, 'en-US');
-  await this.waitForPumpkinParseStrategy_('en-US');
+  await this.waitForPumpkinParseStrategy_();
   await this.runPumpkinParseTestCase(
       new ParseTestCase('copy selected text', {name: 'COPY_SELECTED_TEXT'}));
 });
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/parse/pumpkin_parse_strategy.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/parse/pumpkin_parse_strategy.js
index 75b905d03..7958df0 100644
--- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/parse/pumpkin_parse_strategy.js
+++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/parse/pumpkin_parse_strategy.js
@@ -44,9 +44,6 @@
     /** @private {boolean} */
     this.requestedPumpkinInstall_ = false;
 
-    /** @private {?function(): void} */
-    this.onPumpkinTaggerReadyChangedForTesting_ = null;
-
     this.init_();
   }
 
@@ -87,7 +84,7 @@
     }
 
     // Create SandboxedPumpkinTagger.
-    this.setPumpkinTaggerReady_(false);
+    this.pumpkinTaggerReady_ = false;
     this.pumpkinData_ = data;
 
     this.worker_ = new Worker(
@@ -121,14 +118,14 @@
         this.pumpkinData_ = null;
         return;
       case PumpkinConstants.FromPumpkinTaggerCommand.FULLY_INITIALIZED:
-        this.setPumpkinTaggerReady_(true);
+        this.pumpkinTaggerReady_ = true;
         this.maybeRefresh_();
         return;
       case PumpkinConstants.FromPumpkinTaggerCommand.TAG_RESULTS:
         this.tagResolver_(command.results);
         return;
       case PumpkinConstants.FromPumpkinTaggerCommand.REFRESHED:
-        this.setPumpkinTaggerReady_(true);
+        this.pumpkinTaggerReady_ = true;
         this.maybeRefresh_();
         return;
     }
@@ -304,7 +301,7 @@
       return;
     }
 
-    this.setPumpkinTaggerReady_(false);
+    this.pumpkinTaggerReady_ = false;
     this.sendToSandboxedPumpkinTagger_({
       type: PumpkinConstants.ToPumpkinTaggerCommand.REFRESH,
       locale: this.locale_,
@@ -341,15 +338,4 @@
   isEnabled() {
     return this.enabled;
   }
-
-  /**
-   * @param {boolean} ready
-   * @private
-   */
-  setPumpkinTaggerReady_(ready) {
-    this.pumpkinTaggerReady_ = ready;
-    if (this.onPumpkinTaggerReadyChangedForTesting_) {
-      this.onPumpkinTaggerReadyChangedForTesting_();
-    }
-  }
 }
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js
index f6f6908..55692e5 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js
@@ -1775,12 +1775,10 @@
    */
   toggleSelection_() {
     if (!ChromeVoxState.instance.pageSel) {
-      ChromeVox.earcons.playEarcon(EarconId.SELECTION);
       ChromeVoxState.instance.pageSel = ChromeVoxRange.current;
       DesktopAutomationInterface.instance.ignoreDocumentSelectionFromAction(
           true);
     } else {
-      ChromeVox.earcons.playEarcon(EarconId.SELECTION_REVERSE);
       const root = ChromeVoxRange.current.start.node.root;
       if (root && root.selectionStartObject && root.selectionEndObject &&
           !isNaN(Number(root.selectionStartOffset)) &&
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/prefs.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/prefs.js
index 4f6a8d4..29ee319 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/prefs.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/prefs.js
@@ -29,12 +29,6 @@
  */
 export class ChromeVoxPrefs {
   constructor() {
-    LocalStorage.set('lastRunVersion', chrome.runtime.getManifest().version);
-
-    // Clear per session preferences.
-    // This is to keep the position dictionary from growing excessively large.
-    LocalStorage.set('position', {});
-
     // Default per session sticky to off.
     LocalStorage.set('sticky', false);
   }
@@ -78,7 +72,6 @@
     for (const pref in ChromeVoxPrefs.DEFAULT_PREFS) {
       prefs[pref] = LocalStorage.get(pref);
     }
-    prefs['version'] = chrome.runtime.getManifest().version;
     return prefs;
   }
 
diff --git a/chrome/browser/resources/chromeos/accessibility/common/testing/mock_accessibility_private.js b/chrome/browser/resources/chromeos/accessibility/common/testing/mock_accessibility_private.js
index 09f4038..8c2c54e 100644
--- a/chrome/browser/resources/chromeos/accessibility/common/testing/mock_accessibility_private.js
+++ b/chrome/browser/resources/chromeos/accessibility/common/testing/mock_accessibility_private.js
@@ -108,9 +108,6 @@
      */
     this.dictationBubbleProps_ = null;
 
-    /** @private {Function} */
-    this.onUpdateDictationBubble_ = null;
-
     /** @private {Set<string>} */
     this.enabledFeatures_ = new Set();
 
@@ -384,21 +381,9 @@
     return this.dictationActivated_;
   }
 
-  /** @param {!Function} listener */
-  addUpdateDictationBubbleListener(listener) {
-    this.onUpdateDictationBubble_ = listener;
-  }
-
-  removeUpdateDictationBubbleListener() {
-    this.onUpdateDictationBubble_ = null;
-  }
-
   /** @param {!chrome.accessibilityPrivate.DictationBubbleProperties} props */
   updateDictationBubble(props) {
     this.dictationBubbleProps_ = props;
-    if (this.onUpdateDictationBubble_) {
-      this.onUpdateDictationBubble_();
-    }
   }
 
   /** @return {!chrome.accessibilityPrivate.DictationBubbleProperties|null} */
diff --git a/chrome/browser/resources/feed/BUILD.gn b/chrome/browser/resources/feed/BUILD.gn
index bd82a0d..beb35ef4 100644
--- a/chrome/browser/resources/feed/BUILD.gn
+++ b/chrome/browser/resources/feed/BUILD.gn
@@ -30,10 +30,7 @@
   enable_input_discovery_for_gn_analyze = false
 
   source = "$target_gen_dir/resources.grd"
-  deps = [
-    ":build_grd",
-    "//chrome/browser/ui/webui/feed:mojo_bindings_js",
-  ]
+  deps = [ ":build_grd" ]
   outputs = [
     "grit/feed_resources.h",
     "grit/feed_resources_map.cc",
diff --git a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_browser_proxy.ts b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_browser_proxy.ts
index a610579..6b873b6e 100644
--- a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_browser_proxy.ts
+++ b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_browser_proxy.ts
@@ -25,6 +25,8 @@
   NOTICE_LEARN_MORE = 11,
   NOTICE_MORE_INFO_OPENED = 12,
   NOTICE_MORE_INFO_CLOSED = 13,
+  CONSENT_MORE_BUTTON_CLICKED = 14,
+  NOTICE_MORE_BUTTON_CLICKED = 15,
 }
 
 export class PrivacySandboxDialogBrowserProxy {
diff --git a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_consent_step.html b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_consent_step.html
index daed24d..0591a584 100644
--- a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_consent_step.html
+++ b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_consent_step.html
@@ -40,7 +40,7 @@
   </div>
 </div>
 <div id="showMoreOverlay" hidden="[[wasScrolledToBottom]]">
-  <cr-button id="moreButton" on-click="onMoreClicked"
+  <cr-button id="moreButton" on-click="onConsentMoreClicked"
       class="action-button" aria-hidden="true" tabindex="-1">
     $i18n{m1DialogMoreButton}
     <iron-icon icon="cr:expand-more"></iron-icon>
diff --git a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_mixin.ts b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_mixin.ts
index b383f7f..deecd51 100644
--- a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_mixin.ts
+++ b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_mixin.ts
@@ -71,11 +71,16 @@
               PrivacySandboxPromptAction.NOTICE_ACKNOWLEDGE);
         }
 
-        onMoreClicked() {
-          // Scroll to reveal next visible portion of the content.
-          const scrollable: HTMLElement =
-              this.shadowRoot!.querySelector('[scrollable]')!;
-          scrollable.scrollBy({top: scrollable.clientHeight});
+        onConsentMoreClicked() {
+          this.onMoreClicked_();
+          this.promptActionOccurred(
+              PrivacySandboxPromptAction.CONSENT_MORE_BUTTON_CLICKED);
+        }
+
+        onNoticeMoreClicked() {
+          this.onMoreClicked_();
+          this.promptActionOccurred(
+              PrivacySandboxPromptAction.NOTICE_MORE_BUTTON_CLICKED);
         }
 
         promptActionOccurred(action: PrivacySandboxPromptAction) {
@@ -174,6 +179,13 @@
           scrollable.classList.toggle(
               'more-content-available', !this.wasScrolledToBottom);
         }
+
+        private onMoreClicked_() {
+          // Scroll to reveal next visible portion of the content.
+          const scrollable: HTMLElement =
+              this.shadowRoot!.querySelector('[scrollable]')!;
+          scrollable.scrollBy({top: scrollable.clientHeight});
+        }
       }
 
       return PrivacySandboxDialogMixin;
@@ -186,7 +198,6 @@
   onNoticeLearnMoreExpandedChanged(newValue: boolean, oldValue: boolean): void;
   onNoticeOpenSettings(): void;
   onNoticeAcknowledge(): void;
-  onMoreClicked(): void;
   maybeShowMoreButton(): Promise<void>;
   whenWasScrolledToBottomForTest(): Promise<void>;
   promptActionOccurred(action: PrivacySandboxPromptAction): void;
diff --git a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_notice_step.html b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_notice_step.html
index 4ab67958..0962f3b 100644
--- a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_notice_step.html
+++ b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_notice_step.html
@@ -59,7 +59,7 @@
   </div>
 </div>
 <div id="showMoreOverlay" hidden="[[wasScrolledToBottom]]">
-  <cr-button id="moreButton" on-click="onMoreClicked"
+  <cr-button id="moreButton" on-click="onNoticeMoreClicked"
       class="action-button" aria-hidden="true" tabindex="-1">
     $i18n{m1DialogMoreButton}
     <iron-icon icon="cr:expand-more"></iron-icon>
diff --git a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_dialog_app.html b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_dialog_app.html
index 4bb327c..7cf39f7 100644
--- a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_dialog_app.html
+++ b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_dialog_app.html
@@ -62,7 +62,7 @@
     </div>
   </div>
   <div id="showMoreOverlay" hidden="[[wasScrolledToBottom]]">
-    <cr-button id="moreButton" on-click="onMoreClicked"
+    <cr-button id="moreButton" on-click="onNoticeMoreClicked"
         class="action-button" aria-hidden="true" tabindex="-1">
       $i18n{m1DialogMoreButton}
       <iron-icon icon="cr:expand-more"></iron-icon>
diff --git a/chrome/browser/resources/side_panel/customize_chrome/themes.html b/chrome/browser/resources/side_panel/customize_chrome/themes.html
index ff590c42..e0f87db 100644
--- a/chrome/browser/resources/side_panel/customize_chrome/themes.html
+++ b/chrome/browser/resources/side_panel/customize_chrome/themes.html
@@ -73,6 +73,17 @@
   .image-container {
     border-radius: 12px;
   }
+
+  #refreshDailyToggleContainer {
+    display: flex;
+    justify-content: space-between;
+    margin: 8px 16px 32px;
+  }
+
+  #refreshDailyToggleTitle {
+    font-size: 13px;
+    line-height: 20px;
+  }
 </style>
 <div id="headerContainer">
   <cr-icon-button on-click="onBackClick_" id="backButton"
@@ -80,6 +91,13 @@
   </cr-icon-button>
   <h1 id="header">[[header_]]</h1>
 </div>
+<div id="refreshDailyToggleContainer">
+  <div id="refreshDailyToggleTitle">$i18n{refreshDaily}</div>
+  <cr-toggle id="refreshDailyToggle" title="$i18n{refreshDaily}"
+      checked="[[isRefreshToggleChecked_]]"
+      on-change="onRefreshDailyToggleChange_">
+  </cr-toggle>
+</div>
 <cr-grid columns="3">
   <template is="dom-repeat" id="themesRepeat" items="[[themes_]]">
     <div class="tile theme" tabindex="0" role="button"
diff --git a/chrome/browser/resources/side_panel/customize_chrome/themes.ts b/chrome/browser/resources/side_panel/customize_chrome/themes.ts
index 6007368..9f18dfa 100644
--- a/chrome/browser/resources/side_panel/customize_chrome/themes.ts
+++ b/chrome/browser/resources/side_panel/customize_chrome/themes.ts
@@ -6,11 +6,14 @@
 import 'chrome://resources/cr_elements/cr_grid/cr_grid.js';
 import 'chrome://resources/cr_elements/cr_icons.css.js';
 import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
+import 'chrome://resources/cr_elements/cr_toggle/cr_toggle.js';
 
+import {CrToggleElement} from 'chrome://resources/cr_elements/cr_toggle/cr_toggle.js';
+import {assert} from 'chrome://resources/js/assert_ts.js';
 import {FocusOutlineManager} from 'chrome://resources/js/focus_outline_manager.js';
 import {DomRepeatEvent, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {BackgroundCollection, CollectionImage, CustomizeChromePageHandlerInterface} from './customize_chrome.mojom-webui.js';
+import {BackgroundCollection, CollectionImage, CustomizeChromePageCallbackRouter, CustomizeChromePageHandlerInterface, Theme} from './customize_chrome.mojom-webui.js';
 import {CustomizeChromeApiProxy} from './customize_chrome_api_proxy.js';
 import {getTemplate} from './themes.html.js';
 
@@ -18,6 +21,7 @@
   $: {
     backButton: HTMLButtonElement,
     header: HTMLElement,
+    refreshDailyToggle: CrToggleElement,
   };
 }
 
@@ -37,27 +41,52 @@
         value: null,
         observer: 'onCollectionChange_',
       },
+      isRefreshToggleChecked_: {
+        type: Boolean,
+        computed: `computeIsRefreshToggleChecked_(theme_, selectedCollection)`,
+      },
+      theme_: {
+        type: Object,
+        value: undefined,
+      },
       themes_: Array,
       header_: String,
     };
   }
 
-  private themes_: CollectionImage[];
-  private header_: string;
   public selectedCollection: BackgroundCollection|null;
 
+  private header_: string;
+  private isRefreshToggleChecked_: boolean;
+  private theme_: Theme|undefined;
+  private themes_: CollectionImage[];
+  private setThemeListenerId_: number|null = null;
+
+  private callbackRouter_: CustomizeChromePageCallbackRouter;
   private pageHandler_: CustomizeChromePageHandlerInterface;
 
   constructor() {
     super();
     this.pageHandler_ = CustomizeChromeApiProxy.getInstance().handler;
+    this.callbackRouter_ = CustomizeChromeApiProxy.getInstance().callbackRouter;
   }
 
   override connectedCallback() {
     super.connectedCallback();
+    this.setThemeListenerId_ =
+        this.callbackRouter_.setTheme.addListener((theme: Theme) => {
+          this.theme_ = theme;
+        });
+    this.pageHandler_.updateTheme();
     FocusOutlineManager.forDocument(document);
   }
 
+  override disconnectedCallback() {
+    super.disconnectedCallback();
+    assert(this.setThemeListenerId_);
+    this.callbackRouter_.removeListener(this.setThemeListenerId_);
+  }
+
   private onCollectionChange_() {
     if (this.selectedCollection) {
       this.pageHandler_.getBackgroundImages(this.selectedCollection!.id)
@@ -84,6 +113,23 @@
         attribution1, attribution2, attributionUrl, imageUrl, previewImageUrl);
     this.dispatchEvent(new Event('theme-select'));
   }
+
+  private computeIsRefreshToggleChecked_(): boolean {
+    if (!this.selectedCollection) {
+      return false;
+    }
+    return !!this.theme_ &&
+        this.selectedCollection!.id === this.theme_.dailyRefreshCollectionId;
+  }
+
+  private onRefreshDailyToggleChange_(e: CustomEvent<boolean>) {
+    if (e.detail) {
+      this.pageHandler_.setDailyRefreshCollectionId(
+          this.selectedCollection!.id);
+    } else {
+      this.pageHandler_.setDailyRefreshCollectionId('');
+    }
+  }
 }
 
 declare global {
diff --git a/chrome/browser/sessions/session_restore_browsertest_chromeos.cc b/chrome/browser/sessions/session_restore_browsertest_chromeos.cc
index 50a22ab..ec1bda8 100644
--- a/chrome/browser/sessions/session_restore_browsertest_chromeos.cc
+++ b/chrome/browser/sessions/session_restore_browsertest_chromeos.cc
@@ -155,9 +155,8 @@
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 
 // Assigns three browser windows to three different desks.
-// https://crbug.com/1337306
 IN_PROC_BROWSER_TEST_F(SessionRestoreTestChromeOS,
-                       DISABLED_PRE_RestoreBrowserWindowsToDesks) {
+                       PRE_RestoreBrowserWindowsToDesks) {
   // Create two more desks so we have three desks in total.
   ash::AutotestDesksApi().CreateNewDesk();
   ash::AutotestDesksApi().CreateNewDesk();
@@ -190,9 +189,8 @@
 
 // Verifies that three windows restored to their right desk after restored. Also
 // verifies that the fourth window is visible on all desks after being restored.
-// https://crbug.com/1337306
 IN_PROC_BROWSER_TEST_F(SessionRestoreTestChromeOS,
-                       DISABLED_RestoreBrowserWindowsToDesks) {
+                       RestoreBrowserWindowsToDesks) {
   auto* browser_list = BrowserList::GetInstance();
   ASSERT_EQ(3u, browser_list->size());
 
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/ManageAccountDevicesLinkView.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/ManageAccountDevicesLinkView.java
index 13c82b6..273f0647 100644
--- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/ManageAccountDevicesLinkView.java
+++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/ManageAccountDevicesLinkView.java
@@ -22,10 +22,12 @@
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.browserservices.intents.WebappConstants;
 import org.chromium.chrome.browser.document.ChromeLauncherActivity;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.signin.services.IdentityServicesProvider;
 import org.chromium.components.browser_ui.widget.RoundedCornerImageView;
 import org.chromium.components.embedder_support.util.UrlConstants;
+import org.chromium.components.signin.Tribool;
 import org.chromium.components.signin.base.AccountInfo;
 import org.chromium.components.signin.identitymanager.ConsentLevel;
 import org.chromium.components.signin.identitymanager.IdentityManager;
@@ -88,17 +90,23 @@
         }
 
         TextView linkView = findViewById(R.id.manage_devices_link);
+        // If the feature is disabled, the email address is displayable by default.
+        final boolean canHaveEmailAddressDisplayed =
+                account.getAccountCapabilities().canHaveEmailAddressDisplayed() == Tribool.TRUE
+                || !ChromeFeatureList.sHideNonDisplayableAccountEmail.isEnabled();
+        final String accountFullNameOrEmail =
+                canHaveEmailAddressDisplayed ? account.getEmail() : account.getFullName();
         if (mShowLink) {
             SpannableString linkText = SpanApplier.applySpans(
                     getResources().getString(
-                            R.string.send_tab_to_self_manage_devices_link, account.getEmail()),
+                            R.string.send_tab_to_self_manage_devices_link, accountFullNameOrEmail),
                     new SpanApplier.SpanInfo("<link>", "</link>",
                             new NoUnderlineClickableSpan(
                                     getContext(), this::openManageDevicesPageInNewTab)));
             linkView.setText(linkText);
             linkView.setMovementMethod(LinkMovementMethod.getInstance());
         } else {
-            linkView.setText(account.getEmail());
+            linkView.setText(accountFullNameOrEmail);
         }
     }
 
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfBottomSheetRenderTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfBottomSheetRenderTest.java
index fa2c8bb..0ef4ede 100644
--- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfBottomSheetRenderTest.java
+++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfBottomSheetRenderTest.java
@@ -4,6 +4,10 @@
 
 package org.chromium.chrome.browser.share.send_tab_to_self;
 
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
+import static androidx.test.espresso.matcher.ViewMatchers.withText;
+
 import static org.mockito.Mockito.when;
 
 import android.graphics.Bitmap;
@@ -14,7 +18,6 @@
 import androidx.appcompat.content.res.AppCompatResources;
 import androidx.test.filters.MediumTest;
 
-import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -23,9 +26,11 @@
 import org.mockito.junit.MockitoRule;
 
 import org.chromium.base.test.util.Feature;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.signin.services.IdentityServicesProvider;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.chrome.test.util.browser.signin.SigninTestRule;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
 import org.chromium.components.signin.base.AccountCapabilities;
 import org.chromium.components.signin.base.AccountInfo;
@@ -66,22 +71,11 @@
     @Mock
     private BottomSheetController mBottomSheetController;
 
-    @Before
-    public void setUp() {
-        // Set up account data to be shown by the UI.
-        AccountInfo account = createFakeAccount();
-        when(mIdentityManager.getPrimaryAccountInfo(ConsentLevel.SIGNIN)).thenReturn(account);
-        when(mIdentityManager.findExtendedAccountInfoByEmailAddress(account.getEmail()))
-                .thenReturn(account);
-        when(mIdentityServicesProvider.getIdentityManager(mProfile)).thenReturn(mIdentityManager);
-        IdentityServicesProvider.setInstanceForTests(mIdentityServicesProvider);
-        Profile.setLastUsedProfileForTesting(mProfile);
-    }
-
     @Test
     @MediumTest
     @Feature("RenderTest")
     public void testDevicePickerBottomSheet() throws Throwable {
+        setUpAccountData(createFakeAccount());
         long todayTimestamp = Calendar.getInstance().getTimeInMillis();
         List<TargetDeviceInfo> devices = Arrays.asList(
                 new TargetDeviceInfo("My Phone", "guid1", FormFactor.PHONE, todayTimestamp),
@@ -99,8 +93,30 @@
 
     @Test
     @MediumTest
+    public void testDevicePickerBottomSheetWithNonDisplayableAccountEmail() throws Throwable {
+        ChromeFeatureList.sHideNonDisplayableAccountEmail.setForTesting(true);
+        AccountInfo account =
+                createFakeAccount(SigninTestRule.NON_DISPLAYABLE_EMAIL_ACCOUNT_CAPABILITIES);
+        setUpAccountData(account);
+        long todayTimestamp = Calendar.getInstance().getTimeInMillis();
+        List<TargetDeviceInfo> devices = Arrays.asList(
+                new TargetDeviceInfo("My Phone", "guid1", FormFactor.PHONE, todayTimestamp),
+                new TargetDeviceInfo("My Computer", "guid2", FormFactor.DESKTOP,
+                        todayTimestamp - TimeUnit.DAYS.toMillis(1)));
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            DevicePickerBottomSheetContent sheetContent =
+                    new DevicePickerBottomSheetContent(getActivity(), JUnitTestGURLs.HTTP_URL,
+                            "Title", mBottomSheetController, devices, mProfile);
+            getActivity().setContentView(sheetContent.getContentView());
+        });
+        onView(withText(account.getEmail())).check(doesNotExist());
+    }
+
+    @Test
+    @MediumTest
     @Feature("RenderTest")
     public void testNoTargetDeviceBottomSheetWithPromoFeatureDisabled() throws Throwable {
+        setUpAccountData(createFakeAccount());
         View view = TestThreadUtils.runOnUiThreadBlockingNoException(() -> {
             NoTargetDeviceBottomSheetContent sheetContent = new NoTargetDeviceBottomSheetContent(
                     getActivity(), /*isPromoFeatureEnabled=*/false);
@@ -114,6 +130,7 @@
     @MediumTest
     @Feature("RenderTest")
     public void testNoTargetDeviceBottomSheetWithPromoFeatureEnabled() throws Throwable {
+        setUpAccountData(createFakeAccount());
         View view = TestThreadUtils.runOnUiThreadBlockingNoException(() -> {
             NoTargetDeviceBottomSheetContent sheetContent = new NoTargetDeviceBottomSheetContent(
                     getActivity(), /*isPromoFeatureEnabled=*/true);
@@ -123,10 +140,30 @@
         mRenderTestRule.render(view, "no_target_device_with_account");
     }
 
+    @Test
+    @MediumTest
+    public void testNoTargetDeviceBottomSheetWithPromoFeatureEnabledWithNonDisplayableAccountEmail()
+            throws Throwable {
+        ChromeFeatureList.sHideNonDisplayableAccountEmail.setForTesting(true);
+        AccountInfo account =
+                createFakeAccount(SigninTestRule.NON_DISPLAYABLE_EMAIL_ACCOUNT_CAPABILITIES);
+        setUpAccountData(account);
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            NoTargetDeviceBottomSheetContent sheetContent = new NoTargetDeviceBottomSheetContent(
+                    getActivity(), /*isPromoFeatureEnabled=*/true);
+            getActivity().setContentView(sheetContent.getContentView());
+        });
+        onView(withText(account.getEmail())).check(doesNotExist());
+    }
+
     // TODO(crbug.com/1219434): This duplicates the account in AccountManagerTestRule, so tests can
     // later adopt the rule without failing the golden diffs. That's not done now because it
     // requires changing the device picker to depend on ProfileDataCache instead of IdentityManager.
     private AccountInfo createFakeAccount() {
+        return createFakeAccount(new AccountCapabilities(new HashMap<>()));
+    }
+
+    private AccountInfo createFakeAccount(AccountCapabilities accountCapabilities) {
         Drawable drawable =
                 AppCompatResources.getDrawable(getActivity(), R.drawable.test_profile_picture);
         Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
@@ -136,6 +173,19 @@
         drawable.draw(canvas);
 
         return new AccountInfo(new CoreAccountId("id"), "test@gmail.com", "gaiaId", "John Doe",
-                "John", bitmap, new AccountCapabilities(new HashMap<>()));
+                "John", bitmap, accountCapabilities);
+    }
+
+    /**
+     * Set up account data to be shown by the UI following createFakeAccount().
+     */
+    private void setUpAccountData(AccountInfo account) {
+        // Set up account data to be shown by the UI.
+        when(mIdentityManager.getPrimaryAccountInfo(ConsentLevel.SIGNIN)).thenReturn(account);
+        when(mIdentityManager.findExtendedAccountInfoByEmailAddress(account.getEmail()))
+                .thenReturn(account);
+        when(mIdentityServicesProvider.getIdentityManager(mProfile)).thenReturn(mIdentityManager);
+        IdentityServicesProvider.setInstanceForTests(mIdentityServicesProvider);
+        Profile.setLastUsedProfileForTesting(mProfile);
     }
 }
diff --git a/chrome/browser/supervised_user/supervised_user_pref_store.cc b/chrome/browser/supervised_user/supervised_user_pref_store.cc
index 52930c4..031dc63 100644
--- a/chrome/browser/supervised_user/supervised_user_pref_store.cc
+++ b/chrome/browser/supervised_user/supervised_user_pref_store.cc
@@ -24,6 +24,7 @@
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/net/safe_search_util.h"
 #include "chrome/common/pref_names.h"
+#include "components/autofill/core/common/autofill_prefs.h"
 #include "components/feed/core/shared_prefs/pref_names.h"
 #include "components/prefs/pref_value_map.h"
 #include "components/signin/public/base/signin_pref_names.h"
@@ -131,6 +132,10 @@
     prefs_->SetBoolean(prefs::kSigninAllowed, false);
     prefs_->SetBoolean(feed::prefs::kEnableSnippets, false);
 
+#if BUILDFLAG(IS_ANDROID)
+    prefs_->SetBoolean(autofill::prefs::kAutofillWalletImportEnabled, false);
+#endif
+
     // Copy supervised user settings to prefs.
     for (const auto& entry : kSupervisedUserSettingsPrefMapping) {
       const base::Value* value = settings.Find(entry.settings_name);
diff --git a/chrome/browser/supervised_user/supervised_user_pref_store_unittest.cc b/chrome/browser/supervised_user/supervised_user_pref_store_unittest.cc
index 3ef30d4..11d3f2b 100644
--- a/chrome/browser/supervised_user/supervised_user_pref_store_unittest.cc
+++ b/chrome/browser/supervised_user/supervised_user_pref_store_unittest.cc
@@ -15,6 +15,7 @@
 #include "chrome/browser/supervised_user/supervised_user_settings_service.h"
 #include "chrome/common/net/safe_search_util.h"
 #include "chrome/common/pref_names.h"
+#include "components/autofill/core/common/autofill_prefs.h"
 #include "components/prefs/testing_pref_store.h"
 #include "components/supervised_user/core/common/features.h"
 #include "extensions/buildflags/buildflags.h"
@@ -161,6 +162,12 @@
   EXPECT_EQ(force_youtube_restrict,
             safe_search_util::YOUTUBE_RESTRICT_MODERATE);
 
+#if BUILDFLAG(IS_ANDROID)
+  EXPECT_THAT(fixture.changed_prefs()->FindBoolByDottedPath(
+                  autofill::prefs::kAutofillWalletImportEnabled),
+              false);
+#endif
+
 #if BUILDFLAG(ENABLE_EXTENSIONS)
   // Permissions requests default to disallowed.
   EXPECT_THAT(fixture.changed_prefs()->FindBoolByDottedPath(
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 42eea1df..6f5e2243 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -4995,8 +4995,6 @@
       "views/side_panel/extensions/extension_side_panel_coordinator.h",
       "views/side_panel/extensions/extension_side_panel_manager.cc",
       "views/side_panel/extensions/extension_side_panel_manager.h",
-      "views/side_panel/extensions/extension_side_panel_utils.cc",
-      "views/side_panel/extensions/extension_side_panel_utils.h",
       "views/side_panel/feed/feed_side_panel_coordinator.cc",
       "views/side_panel/feed/feed_side_panel_coordinator.h",
       "views/side_panel/history_clusters/history_clusters_side_panel_coordinator.cc",
@@ -5125,6 +5123,8 @@
       "views/tabs/tab_group_header.h",
       "views/tabs/tab_group_highlight.cc",
       "views/tabs/tab_group_highlight.h",
+      "views/tabs/tab_group_style.cc",
+      "views/tabs/tab_group_style.h",
       "views/tabs/tab_group_underline.cc",
       "views/tabs/tab_group_underline.h",
       "views/tabs/tab_group_views.cc",
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SigninUtils.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SigninUtils.java
index f8702aad..6c2dff7 100644
--- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SigninUtils.java
+++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SigninUtils.java
@@ -6,11 +6,15 @@
 
 import android.accounts.Account;
 import android.app.Activity;
+import android.content.Context;
 import android.content.Intent;
 import android.os.Build;
 import android.provider.Settings;
+import android.text.TextUtils;
 
 import org.chromium.base.IntentUtils;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.chrome.browser.signin.services.DisplayableProfileData;
 
 /**
  * Helper functions for sign-in and accounts.
@@ -45,4 +49,29 @@
     public static boolean openSettingsForAllAccounts(Activity activity) {
         return IntentUtils.safeStartActivity(activity, new Intent(Settings.ACTION_SYNC_SETTINGS));
     }
+
+    /**
+     * Return the appropriate string for 'Continue as John Doe' button, given that
+     * 'Continue as john.doe@example.com' is used as a fallback and certain accounts cannot have
+     * their email address displayed. In such case, use 'Continue' instead.
+     *
+     * @param context The Android Context used to inflate the View.
+     * @param profileData Cached DisplayableProfileData containing the full name and the email
+     *         address.
+     * @return Appropriate string for continueButton.
+     */
+    public static String getContinueAsButtonText(
+            final Context context, DisplayableProfileData profileData) {
+        if (!TextUtils.isEmpty(profileData.getGivenName())) {
+            return context.getString(R.string.sync_promo_continue_as, profileData.getGivenName());
+        }
+        if (!TextUtils.isEmpty(profileData.getFullName())) {
+            return context.getString(R.string.sync_promo_continue_as, profileData.getFullName());
+        }
+        if (!profileData.hasDisplayableEmailAddress()
+                && ChromeFeatureList.sHideNonDisplayableAccountEmail.isEnabled()) {
+            return context.getString(R.string.sync_promo_continue);
+        }
+        return context.getString(R.string.sync_promo_continue_as, profileData.getAccountEmail());
+    }
 }
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SyncPromoController.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SyncPromoController.java
index d3b0524..55c3011c 100644
--- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SyncPromoController.java
+++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SyncPromoController.java
@@ -454,8 +454,8 @@
             view.getSecondaryButton().setVisibility(View.GONE);
             return;
         }
-        view.getPrimaryButton().setText(context.getString(
-                R.string.sync_promo_continue_as, mProfileData.getGivenNameOrFullNameOrEmail()));
+
+        view.getPrimaryButton().setText(SigninUtils.getContinueAsButtonText(context, mProfileData));
 
         view.getSecondaryButton().setText(R.string.signin_promo_choose_another_account);
         view.getSecondaryButton().setOnClickListener(v -> signinWithNotDefaultAccount(context));
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetView.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetView.java
index a38ec9e..4ba3d5b 100644
--- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetView.java
+++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetView.java
@@ -21,6 +21,7 @@
 import org.chromium.base.supplier.ObservableSupplierImpl;
 import org.chromium.chrome.browser.signin.services.DisplayableProfileData;
 import org.chromium.chrome.browser.ui.signin.R;
+import org.chromium.chrome.browser.ui.signin.SigninUtils;
 import org.chromium.chrome.browser.ui.signin.account_picker.AccountPickerBottomSheetProperties.ViewState;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetContent;
 import org.chromium.ui.widget.ButtonCompat;
@@ -160,9 +161,8 @@
         ExistingAccountRowViewBinder.bindAccountView(accountProfileData, mSelectedAccountView);
 
         ButtonCompat continueButton = view.findViewById(R.id.account_picker_continue_as_button);
-        String continueAsButtonText = mActivity.getString(R.string.sync_promo_continue_as,
-                accountProfileData.getGivenNameOrFullNameOrEmail());
-        continueButton.setText(continueAsButtonText);
+        continueButton.setText(
+                SigninUtils.getContinueAsButtonText(view.getContext(), accountProfileData));
     }
 
     /**
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/ExistingAccountRowViewBinder.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/ExistingAccountRowViewBinder.java
index 1018d60..6e45b9d5 100644
--- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/ExistingAccountRowViewBinder.java
+++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/ExistingAccountRowViewBinder.java
@@ -9,6 +9,7 @@
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.signin.services.DisplayableProfileData;
 import org.chromium.chrome.browser.ui.signin.R;
 import org.chromium.chrome.browser.ui.signin.account_picker.AccountPickerProperties.ExistingAccountRowProperties;
@@ -40,6 +41,41 @@
         }
     }
 
+    private static void setAccountTextPrimary(
+            DisplayableProfileData profileData, View accountView) {
+        TextView accountTextPrimary = accountView.findViewById(R.id.account_text_primary);
+        if (!TextUtils.isEmpty(profileData.getFullName())) {
+            accountTextPrimary.setText(profileData.getFullName());
+        } else if (!profileData.hasDisplayableEmailAddress()
+                && ChromeFeatureList.sHideNonDisplayableAccountEmail.isEnabled()) {
+            // Cannot display the email address and empty full name; use default account string.
+            accountTextPrimary.setText(R.string.default_google_account_username);
+        } else {
+            // Full name is not available, show the email address.
+            accountTextPrimary.setText(profileData.getAccountEmail());
+        }
+    }
+
+    private static void setAccountTextSecondary(
+            DisplayableProfileData profileData, View accountView) {
+        TextView accountTextSecondary = accountView.findViewById(R.id.account_text_secondary);
+        if (!profileData.hasDisplayableEmailAddress()
+                && ChromeFeatureList.sHideNonDisplayableAccountEmail.isEnabled()) {
+            // If the email address cannot be displayed, the primary TextView either displays the
+            // full name or the default account string. The secondary TextView is hidden.
+            accountTextSecondary.setVisibility(View.GONE);
+        } else {
+            // If the full name is available, the email will be in the secondary TextView.
+            // Otherwise, the email is in the primary TextView; the secondary TextView hidden.
+            final int secondaryTextVisibility =
+                    TextUtils.isEmpty(profileData.getFullName()) ? View.GONE : View.VISIBLE;
+            if (secondaryTextVisibility == View.VISIBLE) {
+                accountTextSecondary.setText(profileData.getAccountEmail());
+            }
+            accountTextSecondary.setVisibility(secondaryTextVisibility);
+        }
+    }
+
     /**
      * Binds the view with the given profile data.
      *
@@ -49,19 +85,7 @@
     public static void bindAccountView(DisplayableProfileData profileData, View view) {
         ImageView accountImage = view.findViewById(R.id.account_image);
         accountImage.setImageDrawable(profileData.getImage());
-
-        TextView accountTextPrimary = view.findViewById(R.id.account_text_primary);
-        TextView accountTextSecondary = view.findViewById(R.id.account_text_secondary);
-
-        String fullName = profileData.getFullName();
-        if (!TextUtils.isEmpty(fullName)) {
-            accountTextPrimary.setText(fullName);
-            accountTextSecondary.setText(profileData.getAccountEmail());
-            accountTextSecondary.setVisibility(View.VISIBLE);
-        } else {
-            // Full name is not available, show the email in the primary TextView.
-            accountTextPrimary.setText(profileData.getAccountEmail());
-            accountTextSecondary.setVisibility(View.GONE);
-        }
+        setAccountTextPrimary(profileData, view);
+        setAccountTextSecondary(profileData, view);
     }
 }
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/SigninFirstRunViewBinder.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/SigninFirstRunViewBinder.java
index 4ec632ef..c3b168b1 100644
--- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/SigninFirstRunViewBinder.java
+++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/SigninFirstRunViewBinder.java
@@ -14,6 +14,7 @@
 
 import org.chromium.chrome.browser.signin.services.DisplayableProfileData;
 import org.chromium.chrome.browser.ui.signin.R;
+import org.chromium.chrome.browser.ui.signin.SigninUtils;
 import org.chromium.chrome.browser.ui.signin.account_picker.ExistingAccountRowViewBinder;
 import org.chromium.ui.modelutil.PropertyKey;
 import org.chromium.ui.modelutil.PropertyModel;
@@ -85,8 +86,8 @@
         } else {
             ExistingAccountRowViewBinder.bindAccountView(
                     profileData, view.getSelectedAccountView());
-            view.getContinueButtonView().setText(view.getContext().getString(
-                    R.string.sync_promo_continue_as, profileData.getGivenNameOrFullNameOrEmail()));
+            view.getContinueButtonView().setText(
+                    SigninUtils.getContinueAsButtonText(view.getContext(), profileData));
         }
         updateVisibility(view, model);
     }
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
index ed417fc..6f3c3d1 100644
--- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
+++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -3087,6 +3087,9 @@
       <message name="IDS_SYNC_PROMO_CONTINUE_AS" desc="Button to sign into Chrome with the displayed account and without having to reenter a password. ‘John’ is replaced with the user’s given name, or the user’s full name if the given name is not available. Ensure consistency with related OneGoogle sign-in buttons (see e.g. TC ID 5569230012177947065).">
         Continue as <ph name="USER_FULL_NAME">%1$s<ex>John</ex></ph>
       </message>
+      <message name="IDS_SYNC_PROMO_CONTINUE" desc="Button to sign into Chrome, similar to IDS_SYNC_PROMO_CONTINUE_AS. Used when the user's display names are not available and the email address cannot be displayed.">
+        Continue
+      </message>
       <message name="IDS_SIGNIN_PROMO_CHOOSE_ACCOUNT" desc="Button that the user can press if they are not the profile that Chrome found (opposite of 'Continue as Joe Doe').">
         Not <ph name="EMAIL">%1$s<ex>john.doe@example.com</ex></ph>?
       </message>
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SYNC_PROMO_CONTINUE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SYNC_PROMO_CONTINUE.png.sha1
new file mode 100644
index 0000000..6d29463d
--- /dev/null
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SYNC_PROMO_CONTINUE.png.sha1
@@ -0,0 +1 @@
+0a3b9c683fbd984f340e85050eb75bb1550986e6
\ No newline at end of file
diff --git a/chrome/browser/ui/android/toolbar/BUILD.gn b/chrome/browser/ui/android/toolbar/BUILD.gn
index 709b871..10fcfc8 100644
--- a/chrome/browser/ui/android/toolbar/BUILD.gn
+++ b/chrome/browser/ui/android/toolbar/BUILD.gn
@@ -288,6 +288,7 @@
 
 robolectric_library("junit") {
   sources = [
+    "java/src/org/chromium/chrome/browser/toolbar/BaseButtonDataProviderTest.java",
     "java/src/org/chromium/chrome/browser/toolbar/ConstraintsCheckerTest.java",
     "java/src/org/chromium/chrome/browser/toolbar/TabCountProviderUnitTest.java",
     "java/src/org/chromium/chrome/browser/toolbar/ToolbarProgressBarTest.java",
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/BaseButtonDataProvider.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/BaseButtonDataProvider.java
index 0c77557..5f2385b 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/BaseButtonDataProvider.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/BaseButtonDataProvider.java
@@ -36,7 +36,6 @@
     private ModalDialogManagerObserver mModalDialogObserver;
 
     private boolean mShouldShowOnIncognitoTabs;
-    private @StringRes int mActionChipResourceId;
 
     /**
      * Creates a new instance of {@code BaseButtonDataProvider}.
@@ -124,17 +123,6 @@
         mButtonData.updateIPHCommandBuilder(getIphCommandBuilder(tab));
     }
 
-    private void maybeSetActionChipResourceId() {
-        if (!mButtonData.getButtonSpec().isDynamicAction() || !FeatureList.isInitialized()
-                || !AdaptiveToolbarFeatures.shouldShowActionChip(
-                        mButtonData.getButtonSpec().getButtonVariant())
-                || mButtonData.getButtonSpec().getActionChipLabelResId() != Resources.ID_NULL) {
-            return;
-        }
-
-        mButtonData.updateActionChipResourceId(mActionChipResourceId);
-    }
-
     /**
      * Sets whether the button should be shown on incognito tabs, default is false.
      */
@@ -143,15 +131,6 @@
     }
 
     /**
-     * Sets a string resource ID to be used when the action chip variant is enabled, only used on
-     * dynamic actions.
-     * @param actionChipResourceId A string resource to use as the action chip label.
-     */
-    protected void setActionChipResourceId(@StringRes int actionChipResourceId) {
-        mActionChipResourceId = actionChipResourceId;
-    }
-
-    /**
      * Gets an {@link IPHCommandBuilder} builder instance to use on this button. Only called when
      * native is initialized and when there's no IPHCommandBuilder set.
      * @param tab Current tab.
@@ -177,7 +156,6 @@
     public ButtonData get(Tab tab) {
         mButtonData.setCanShow(shouldShowButton(tab));
         maybeSetIphCommandBuilder(tab);
-        maybeSetActionChipResourceId();
 
         return mButtonData;
     }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/BaseButtonDataProviderTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/BaseButtonDataProviderTest.java
new file mode 100644
index 0000000..4c2361e3
--- /dev/null
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/BaseButtonDataProviderTest.java
@@ -0,0 +1,157 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.toolbar;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+
+import androidx.annotation.Nullable;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+import org.robolectric.annotation.Config;
+
+import org.chromium.base.FeatureList;
+import org.chromium.base.supplier.ObservableSupplier;
+import org.chromium.base.supplier.Supplier;
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.chrome.R;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.toolbar.adaptive.AdaptiveToolbarButtonVariant;
+import org.chromium.chrome.browser.user_education.IPHCommandBuilder;
+import org.chromium.chrome.test.util.browser.Features;
+import org.chromium.components.feature_engagement.FeatureConstants;
+import org.chromium.ui.modaldialog.ModalDialogManager;
+
+/**
+ * Unit test for {@link BaseButtonDataProvider}.
+ */
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+@Features.EnableFeatures({ChromeFeatureList.CONTEXTUAL_PAGE_ACTION_PRICE_TRACKING,
+        ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION_V2})
+public class BaseButtonDataProviderTest {
+    private class TestButtonDataProvider extends BaseButtonDataProvider {
+        public TestButtonDataProvider(Supplier<Tab> activeTabSupplier,
+                @Nullable ModalDialogManager modalDialogManager, Drawable buttonDrawable,
+                int contentDescriptionResId, int actionChipLabelResId, boolean supportsTinting,
+                int adaptiveButtonVariant) {
+            super(activeTabSupplier, modalDialogManager, buttonDrawable, contentDescriptionResId,
+                    actionChipLabelResId, supportsTinting, null, adaptiveButtonVariant);
+        }
+
+        @Override
+        protected IPHCommandBuilder getIphCommandBuilder(Tab tab) {
+            IPHCommandBuilder iphCommandBuilder =
+                    new IPHCommandBuilder(tab.getContext().getResources(),
+                            FeatureConstants.CONTEXTUAL_PAGE_ACTIONS_QUIET_VARIANT,
+                            /* stringId = */ R.string.iph_price_tracking_menu_item,
+                            /* accessibilityStringId = */ R.string.iph_price_tracking_menu_item);
+            return iphCommandBuilder;
+        }
+
+        @Override
+        public void onClick(View view) {}
+    }
+
+    @Rule
+    public TestRule mFeaturesProcessor = new Features.JUnitProcessor();
+
+    private Activity mActivity;
+    @Mock
+    private Tab mMockTab;
+    @Mock
+    private ObservableSupplier<Tab> mMockTabSupplier;
+    @Mock
+    private ModalDialogManager mMockModalDialogManager;
+
+    @Before
+    public void setUp() {
+        mActivity = Robolectric.setupActivity(Activity.class);
+        mActivity.setTheme(R.style.Theme_BrowserUI_DayNight);
+
+        MockitoAnnotations.initMocks(this);
+
+        when(mMockTab.getContext()).thenReturn(mActivity);
+        when(mMockTabSupplier.get()).thenReturn(mMockTab);
+    }
+
+    @Test
+    public void testButtonData_QuietVariation() {
+        TestButtonDataProvider testButtonDataProvider =
+                new TestButtonDataProvider(mMockTabSupplier, mMockModalDialogManager,
+                        mock(Drawable.class), R.string.enable_price_tracking_menu_item,
+                        /* actionChipLabelResId= */ R.string.enable_price_tracking_menu_item,
+                        /* supportsTinting = */ true, AdaptiveToolbarButtonVariant.PRICE_TRACKING);
+        ButtonData buttonData = testButtonDataProvider.get(mMockTab);
+
+        // Quiet variation uses an IPHCommandBuilder to highlight the action.
+        Assert.assertNotNull(buttonData.getButtonSpec().getIPHCommandBuilder());
+    }
+
+    @Test
+    public void testButtonData_ActionChipVariation() {
+        FeatureList.TestValues testValues = new FeatureList.TestValues();
+        testValues.addFeatureFlagOverride(ChromeFeatureList.CONTEXTUAL_PAGE_ACTIONS, true);
+        testValues.addFieldTrialParamOverride(
+                ChromeFeatureList.CONTEXTUAL_PAGE_ACTION_PRICE_TRACKING, "action_chip", "true");
+        testValues.addFeatureFlagOverride(
+                ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION_V2, true);
+        FeatureList.setTestValues(testValues);
+
+        TestButtonDataProvider testButtonDataProvider =
+                new TestButtonDataProvider(mMockTabSupplier, mMockModalDialogManager,
+                        mock(Drawable.class), R.string.enable_price_tracking_menu_item,
+                        /* actionChipLabelResId= */ R.string.enable_price_tracking_menu_item,
+                        /* supportsTinting = */ true, AdaptiveToolbarButtonVariant.PRICE_TRACKING);
+        ButtonData buttonData = testButtonDataProvider.get(mMockTab);
+
+        // Action chip variation should not set an IPH command builder.
+        Assert.assertNull(buttonData.getButtonSpec().getIPHCommandBuilder());
+    }
+
+    @Test
+    public void testSetShouldShowOnIncognito_defaultBehavior() {
+        TestButtonDataProvider testButtonDataProvider =
+                new TestButtonDataProvider(mMockTabSupplier, mMockModalDialogManager,
+                        mock(Drawable.class), R.string.enable_price_tracking_menu_item,
+                        /* actionChipLabelResId= */ R.string.enable_price_tracking_menu_item,
+                        /* supportsTinting = */ true, AdaptiveToolbarButtonVariant.PRICE_TRACKING);
+
+        when(mMockTab.isIncognito()).thenReturn(true);
+
+        ButtonData buttonDataIncognitoTab = testButtonDataProvider.get(mMockTab);
+
+        Assert.assertFalse(buttonDataIncognitoTab.canShow());
+    }
+
+    @Test
+    public void testSetShouldShowOnIncognito_showOnIncognito() {
+        TestButtonDataProvider testButtonDataProvider =
+                new TestButtonDataProvider(mMockTabSupplier, mMockModalDialogManager,
+                        mock(Drawable.class), R.string.enable_price_tracking_menu_item,
+                        /* actionChipLabelResId= */ R.string.enable_price_tracking_menu_item,
+                        /* supportsTinting = */ true, AdaptiveToolbarButtonVariant.PRICE_TRACKING);
+
+        when(mMockTab.isIncognito()).thenReturn(true);
+        testButtonDataProvider.setShouldShowOnIncognitoTabs(true);
+
+        ButtonData buttonDataIncognitoTab = testButtonDataProvider.get(mMockTab);
+
+        Assert.assertTrue(buttonDataIncognitoTab.canShow());
+    }
+}
diff --git a/chrome/browser/ui/media_router/media_router_ui.cc b/chrome/browser/ui/media_router/media_router_ui.cc
index 38e46b7f..535eb0b 100644
--- a/chrome/browser/ui/media_router/media_router_ui.cc
+++ b/chrome/browser/ui/media_router/media_router_ui.cc
@@ -415,8 +415,7 @@
       break;
   }
 
-  IssueInfo issue_info(issue_title, IssueInfo::Action::DISMISS,
-                       IssueInfo::Severity::NOTIFICATION);
+  IssueInfo issue_info(issue_title, IssueInfo::Severity::NOTIFICATION);
   issue_info.sink_id = sink_id;
   AddIssue(issue_info);
 }
@@ -435,8 +434,7 @@
   std::string issue_title = l10n_util::GetStringFUTF8(
       IDS_MEDIA_ROUTER_ISSUE_CREATE_ROUTE_USER_NOT_ALLOWED,
       GetSinkFriendlyNameFromId(sink_id));
-  IssueInfo issue_info(issue_title, IssueInfo::Action::DISMISS,
-                       IssueInfo::Severity::WARNING);
+  IssueInfo issue_info(issue_title, IssueInfo::Severity::WARNING);
   issue_info.sink_id = sink_id;
   AddIssue(issue_info);
 }
@@ -446,8 +444,7 @@
   std::string issue_title = l10n_util::GetStringFUTF8(
       IDS_MEDIA_ROUTER_ISSUE_CREATE_ROUTE_NOTIFICATION_DISABLED,
       GetSinkFriendlyNameFromId(sink_id));
-  IssueInfo issue_info(issue_title, IssueInfo::Action::DISMISS,
-                       IssueInfo::Severity::WARNING);
+  IssueInfo issue_info(issue_title, IssueInfo::Severity::WARNING);
   issue_info.sink_id = sink_id;
   AddIssue(issue_info);
 }
@@ -456,8 +453,7 @@
 #if BUILDFLAG(IS_MAC)
   std::string issue_title = l10n_util::GetStringUTF8(
       IDS_MEDIA_ROUTER_ISSUE_MAC_SCREEN_CAPTURE_PERMISSION_ERROR);
-  IssueInfo issue_info(issue_title, IssueInfo::Action::DISMISS,
-                       IssueInfo::Severity::WARNING);
+  IssueInfo issue_info(issue_title, IssueInfo::Severity::WARNING);
   issue_info.sink_id = sink_id;
   AddIssue(issue_info);
 #else
@@ -475,8 +471,7 @@
                 IDS_MEDIA_ROUTER_ISSUE_UNABLE_TO_CAST_DESKTOP)
           : l10n_util::GetStringUTF8(
                 IDS_MEDIA_ROUTER_ISSUE_CREATE_ROUTE_TIMEOUT_FOR_TAB);
-  IssueInfo issue_info(issue_title, IssueInfo::Action::DISMISS,
-                       IssueInfo::Severity::WARNING);
+  IssueInfo issue_info(issue_title, IssueInfo::Severity::WARNING);
   issue_info.sink_id = sink_id;
   AddIssue(issue_info);
 }
@@ -485,7 +480,7 @@
     const MediaSink::Id& sink_id) {
   IssueInfo issue_info(
       l10n_util::GetStringUTF8(IDS_MEDIA_ROUTER_ISSUE_TAB_AUDIO_NOT_SUPPORTED),
-      IssueInfo::Action::DISMISS, IssueInfo::Severity::NOTIFICATION);
+      IssueInfo::Severity::NOTIFICATION);
   issue_info.sink_id = sink_id;
   AddIssue(issue_info);
 }
diff --git a/chrome/browser/ui/media_router/media_router_ui_unittest.cc b/chrome/browser/ui/media_router/media_router_ui_unittest.cc
index c4a8789..2ed86dc 100644
--- a/chrome/browser/ui/media_router/media_router_ui_unittest.cc
+++ b/chrome/browser/ui/media_router/media_router_ui_unittest.cc
@@ -455,8 +455,7 @@
   NiceMock<MockIssuesObserver> issues_observer(mock_router_->GetIssueManager());
   issues_observer.Init();
   const std::string issue_title("Issue 1");
-  IssueInfo issue(issue_title, IssueInfo::Action::DISMISS,
-                  IssueInfo::Severity::WARNING);
+  IssueInfo issue(issue_title, IssueInfo::Severity::WARNING);
   issue.sink_id = sink2.id();
   Issue::Id issue_id = -1;
 
diff --git a/chrome/browser/ui/toolbar/media_router_action_controller_unittest.cc b/chrome/browser/ui/toolbar/media_router_action_controller_unittest.cc
index ae00cdbc..6531ea7 100644
--- a/chrome/browser/ui/toolbar/media_router_action_controller_unittest.cc
+++ b/chrome/browser/ui/toolbar/media_router_action_controller_unittest.cc
@@ -40,7 +40,6 @@
   MediaRouterActionControllerUnitTest()
       : issue_(media_router::IssueInfo(
             "title notification",
-            media_router::IssueInfo::Action::DISMISS,
             media_router::IssueInfo::Severity::NOTIFICATION)) {}
 
   MediaRouterActionControllerUnitTest(
diff --git a/chrome/browser/ui/views/commerce/price_tracking_icon_view.cc b/chrome/browser/ui/views/commerce/price_tracking_icon_view.cc
index 23c1fca..29622b0 100644
--- a/chrome/browser/ui/views/commerce/price_tracking_icon_view.cc
+++ b/chrome/browser/ui/views/commerce/price_tracking_icon_view.cc
@@ -205,7 +205,8 @@
           BrowserView::GetBrowserViewForBrowser(browser_)
               ->side_panel_coordinator();
       if (coordinator) {
-        SidePanelRegistry* registry = coordinator->GetGlobalSidePanelRegistry();
+        SidePanelRegistry* registry =
+            SidePanelCoordinator::GetGlobalSidePanelRegistry(browser_);
         registry->SetActiveEntry(registry->GetEntryForKey(
             SidePanelEntry::Key(SidePanelEntry::Id::kBookmarks)));
       } else {
diff --git a/chrome/browser/ui/views/commerce/price_tracking_icon_view_interactive_uitest.cc b/chrome/browser/ui/views/commerce/price_tracking_icon_view_interactive_uitest.cc
index 21cc902..eefd88d 100644
--- a/chrome/browser/ui/views/commerce/price_tracking_icon_view_interactive_uitest.cc
+++ b/chrome/browser/ui/views/commerce/price_tracking_icon_view_interactive_uitest.cc
@@ -796,7 +796,8 @@
   // show bookmark tab in side panel.
   EXPECT_TRUE(promo_controller->IsPromoActive(
       feature_engagement::kIPHPriceTrackingInSidePanelFeature));
-  SidePanelRegistry* registry = coordinator->GetGlobalSidePanelRegistry();
+  SidePanelRegistry* registry =
+      SidePanelCoordinator::GetGlobalSidePanelRegistry(browser());
   EXPECT_TRUE(registry->active_entry().has_value());
   EXPECT_EQ(registry->active_entry().value()->key().id(),
             SidePanelEntry::Id::kBookmarks);
@@ -844,7 +845,8 @@
   // show bookmark tab in side panel.
   EXPECT_FALSE(promo_controller->IsPromoActive(
       feature_engagement::kIPHPriceTrackingInSidePanelFeature));
-  SidePanelRegistry* registry = coordinator->GetGlobalSidePanelRegistry();
+  SidePanelRegistry* registry =
+      SidePanelCoordinator::GetGlobalSidePanelRegistry(browser());
   EXPECT_FALSE(registry->active_entry().has_value());
   EXPECT_FALSE(prefs->GetBoolean(prefs::kShouldShowSidePanelBookmarkTab));
 }
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_coordinator.cc b/chrome/browser/ui/views/extensions/extensions_menu_coordinator.cc
index 9b06b66..15c1cc2f 100644
--- a/chrome/browser/ui/views/extensions/extensions_menu_coordinator.cc
+++ b/chrome/browser/ui/views/extensions/extensions_menu_coordinator.cc
@@ -7,7 +7,6 @@
 #include <memory>
 
 #include "base/feature_list.h"
-#include "chrome/browser/ui/views/controls/page_switcher_view.h"
 #include "chrome/browser/ui/views/extensions/extensions_menu_view_controller.h"
 #include "extensions/common/extension_features.h"
 #include "ui/views/bubble/bubble_dialog_delegate_view.h"
@@ -38,14 +37,13 @@
   bubble_delegate->SetButtons(ui::DIALOG_BUTTON_NONE);
   bubble_delegate->SetEnableArrowKeyTraversal(true);
 
-  auto empty_initial_page = std::make_unique<views::View>();
-  auto* contents_view = bubble_delegate->SetContentsView(
-      std::make_unique<PageSwitcherView>(std::move(empty_initial_page)));
-  contents_view->View::AddObserver(this);
-  bubble_tracker_.SetView(contents_view);
+  auto* bubble_contents = bubble_delegate->SetContentsView(
+      views::Builder<views::View>().SetUseDefaultFillLayout(true).Build());
+  bubble_contents->View::AddObserver(this);
+  bubble_tracker_.SetView(bubble_contents);
 
   controller_ = std::make_unique<ExtensionsMenuViewController>(
-      browser_, extensions_container, contents_view, bubble_delegate.get());
+      browser_, extensions_container, bubble_contents, bubble_delegate.get());
   controller_->OpenMainPage();
 
   views::BubbleDialogDelegate::CreateBubble(std::move(bubble_delegate))->Show();
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_view_controller.cc b/chrome/browser/ui/views/extensions/extensions_menu_view_controller.cc
index 71ea04b6..c9386b1 100644
--- a/chrome/browser/ui/views/extensions/extensions_menu_view_controller.cc
+++ b/chrome/browser/ui/views/extensions/extensions_menu_view_controller.cc
@@ -8,7 +8,6 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/extensions/extension_action_view_controller.h"
 #include "chrome/browser/ui/extensions/extensions_container.h"
-#include "chrome/browser/ui/views/controls/page_switcher_view.h"
 #include "chrome/browser/ui/views/extensions/extensions_menu_main_page_view.h"
 #include "chrome/browser/ui/views/extensions/extensions_menu_page_view.h"
 #include "chrome/browser/ui/views/extensions/extensions_menu_site_permissions_page_view.h"
@@ -37,12 +36,12 @@
 ExtensionsMenuViewController::ExtensionsMenuViewController(
     Browser* browser,
     ExtensionsContainer* extensions_container,
-    PageSwitcherView* contents_view,
-    views::BubbleDialogDelegate* dialog_delegate)
+    views::View* bubble_contents,
+    views::BubbleDialogDelegate* bubble_delegate)
     : browser_(browser),
       extensions_container_(extensions_container),
-      contents_view_(contents_view),
-      dialog_delegate_(dialog_delegate),
+      bubble_contents_(bubble_contents),
+      bubble_delegate_(bubble_delegate),
       toolbar_model_(ToolbarActionsModel::Get(browser_->profile())) {
   browser_->tab_strip_model()->AddObserver(this);
 }
@@ -74,27 +73,23 @@
 }
 
 void ExtensionsMenuViewController::CloseBubble() {
-  contents_view_->GetWidget()->CloseWithReason(
+  bubble_contents_->GetWidget()->CloseWithReason(
       views::Widget::ClosedReason::kCloseButtonClicked);
 }
 
 void ExtensionsMenuViewController::TabChangedAt(content::WebContents* contents,
                                                 int index,
                                                 TabChangeType change_type) {
-  auto* current_page = views::AsViewClass<ExtensionsMenuPageView>(
-      contents_view_->GetCurrentPage());
-  DCHECK(current_page);
-  current_page->Update();
+  DCHECK(current_page_);
+  current_page_->Update();
 }
 
 void ExtensionsMenuViewController::OnTabStripModelChanged(
     TabStripModel* tab_strip_model,
     const TabStripModelChange& change,
     const TabStripSelectionChange& selection) {
-  auto* current_page = views::AsViewClass<ExtensionsMenuPageView>(
-      contents_view_->GetCurrentPage());
-  DCHECK(current_page);
-  current_page->Update();
+  DCHECK(current_page_);
+  current_page_->Update();
 }
 
 // TODO(crbug.com/1390952): Listen for "toolbar pinned actions changed" to
@@ -103,19 +98,20 @@
 
 ExtensionsMenuMainPageView*
 ExtensionsMenuViewController::GetMainPageViewForTesting() {
-  return views::AsViewClass<ExtensionsMenuMainPageView>(
-      contents_view_->GetCurrentPage());
+  DCHECK(current_page_);
+  return views::AsViewClass<ExtensionsMenuMainPageView>(current_page_);
 }
 
-// TODO(crbug.com/1390952): Move page switching logic from the PageSwitcherView
-// to the view controller, as PageSwitcherView doesn't actually have "view"
-// responsibilities
 void ExtensionsMenuViewController::SwitchToPage(
-    std::unique_ptr<views::View> page) {
-  contents_view_->SwitchToPage(std::move(page));
+    std::unique_ptr<ExtensionsMenuPageView> page) {
+  if (current_page_) {
+    bubble_contents_->RemoveChildViewT(current_page_.get());
+  }
+  current_page_ = bubble_contents_->AddChildView(std::move(page));
+
   // Only resize the menu if the bubble is created, since page could be added to
   // the menu beforehand and delegate wouldn't know the bubble bounds.
-  if (dialog_delegate_->GetBubbleFrameView()) {
-    dialog_delegate_->SizeToContents();
+  if (bubble_delegate_->GetBubbleFrameView()) {
+    bubble_delegate_->SizeToContents();
   }
 }
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_view_controller.h b/chrome/browser/ui/views/extensions/extensions_menu_view_controller.h
index 5f3428d3..fcd67b3 100644
--- a/chrome/browser/ui/views/extensions/extensions_menu_view_controller.h
+++ b/chrome/browser/ui/views/extensions/extensions_menu_view_controller.h
@@ -15,8 +15,8 @@
 }  // namespace views
 
 class Browser;
-class PageSwitcherView;
 class ExtensionsContainer;
+class ExtensionsMenuPageView;
 class ExtensionsMenuMainPageView;
 class ToolbarActionsModel;
 
@@ -25,7 +25,7 @@
  public:
   ExtensionsMenuViewController(Browser* browser,
                                ExtensionsContainer* extensions_container,
-                               PageSwitcherView* contents_view,
+                               views::View* bubble_contents,
                                views::BubbleDialogDelegate* dialog_delegate);
   ExtensionsMenuViewController(const ExtensionsMenuViewController&) = delete;
   const ExtensionsMenuViewController& operator=(
@@ -54,14 +54,17 @@
 
  private:
   // Switches the current page to `page`.
-  void SwitchToPage(std::unique_ptr<views::View> page);
+  void SwitchToPage(std::unique_ptr<ExtensionsMenuPageView> page);
 
   const raw_ptr<Browser> browser_;
   const raw_ptr<ExtensionsContainer> extensions_container_;
-  const raw_ptr<PageSwitcherView> contents_view_;
-  const raw_ptr<views::BubbleDialogDelegate> dialog_delegate_;
+  const raw_ptr<views::View> bubble_contents_;
+  const raw_ptr<views::BubbleDialogDelegate> bubble_delegate_;
 
   const raw_ptr<ToolbarActionsModel> toolbar_model_;
+
+  // The current page visible in `bubble_contents_`.
+  raw_ptr<ExtensionsMenuPageView> current_page_ = nullptr;
 };
 
 #endif  // CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSIONS_MENU_VIEW_CONTROLLER_H_
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc
index 2c8428c..4ebce1d1 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc
@@ -190,8 +190,8 @@
        browser_view()->AppUsesWindowControlsOverlay() ||
        browser_view()->AppUsesBorderlessMode())) {
     // Add the container for extra web app buttons (e.g app menu button).
-    set_web_app_frame_toolbar(AddChildView(
-        std::make_unique<WebAppFrameToolbarView>(frame(), browser_view())));
+    set_web_app_frame_toolbar(
+        AddChildView(std::make_unique<WebAppFrameToolbarView>(browser_view())));
     if (AppIsBorderlessPwa())
       UpdateBorderlessModeEnabled();
   }
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm
index a861357..925bf50c 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm
@@ -88,8 +88,8 @@
 
   if (browser_view->GetIsWebAppType()) {
     if (browser_view->browser()->app_controller()) {
-      set_web_app_frame_toolbar(AddChildView(
-          std::make_unique<WebAppFrameToolbarView>(frame, browser_view)));
+      set_web_app_frame_toolbar(
+          AddChildView(std::make_unique<WebAppFrameToolbarView>(browser_view)));
 
       if (browser_view->IsWindowControlsOverlayEnabled()) {
         caption_button_placeholder_container_ =
diff --git a/chrome/browser/ui/views/frame/glass_browser_frame_view.cc b/chrome/browser/ui/views/frame/glass_browser_frame_view.cc
index 0e9678f..cb48c27 100644
--- a/chrome/browser/ui/views/frame/glass_browser_frame_view.cc
+++ b/chrome/browser/ui/views/frame/glass_browser_frame_view.cc
@@ -98,8 +98,8 @@
   web_app::AppBrowserController* controller =
       browser_view->browser()->app_controller();
   if (controller) {
-    set_web_app_frame_toolbar(AddChildView(
-        std::make_unique<WebAppFrameToolbarView>(frame, browser_view)));
+    set_web_app_frame_toolbar(
+        AddChildView(std::make_unique<WebAppFrameToolbarView>(browser_view)));
   }
 
   // The window title appears above the web app frame toolbar (if present),
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc
index 99f07b0..405d00d 100644
--- a/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc
+++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc
@@ -216,8 +216,8 @@
   }
 
   if (controller) {
-    set_web_app_frame_toolbar(AddChildView(
-        std::make_unique<WebAppFrameToolbarView>(frame(), browser_view())));
+    set_web_app_frame_toolbar(
+        AddChildView(std::make_unique<WebAppFrameToolbarView>(browser_view())));
   }
 
   // The window title appears above the web app frame toolbar (if present),
diff --git a/chrome/browser/ui/views/global_media_controls/media_item_ui_device_selector_view_unittest.cc b/chrome/browser/ui/views/global_media_controls/media_item_ui_device_selector_view_unittest.cc
index 55b7348..c3bcc6cc 100644
--- a/chrome/browser/ui/views/global_media_controls/media_item_ui_device_selector_view_unittest.cc
+++ b/chrome/browser/ui/views/global_media_controls/media_item_ui_device_selector_view_unittest.cc
@@ -549,8 +549,7 @@
   // cast session.
   auto sink = CreateMediaSink();
   media_router::IssueInfo issue_info(
-      "Issue Title", media_router::IssueInfo::Action::DISMISS,
-      media_router::IssueInfo::Severity::WARNING);
+      "Issue Title", media_router::IssueInfo::Severity::WARNING);
   media_router::Issue issue(issue_info);
   sink.issue = issue;
 
diff --git a/chrome/browser/ui/views/media_router/cast_dialog_sink_button_unittest.cc b/chrome/browser/ui/views/media_router/cast_dialog_sink_button_unittest.cc
index d3fae40..cb0cdf1 100644
--- a/chrome/browser/ui/views/media_router/cast_dialog_sink_button_unittest.cc
+++ b/chrome/browser/ui/views/media_router/cast_dialog_sink_button_unittest.cc
@@ -74,8 +74,7 @@
 
 TEST_F(CastDialogSinkButtonTest, SetStatusLabelForSinkWithIssue) {
   UIMediaSink sink{mojom::MediaRouteProviderId::CAST};
-  sink.issue = Issue(IssueInfo("issue", IssueInfo::Action::DISMISS,
-                               IssueInfo::Severity::WARNING));
+  sink.issue = Issue(IssueInfo("issue", IssueInfo::Severity::WARNING));
   // Issue info should be the status text regardless of the sink state.
   sink.state = UIMediaSinkState::AVAILABLE;
   CastDialogSinkButton button1(views::Button::PressedCallback(), sink);
diff --git a/chrome/browser/ui/views/media_router/cast_dialog_view_unittest.cc b/chrome/browser/ui/views/media_router/cast_dialog_view_unittest.cc
index c2a0f02..5326467 100644
--- a/chrome/browser/ui/views/media_router/cast_dialog_view_unittest.cc
+++ b/chrome/browser/ui/views/media_router/cast_dialog_view_unittest.cc
@@ -190,8 +190,8 @@
 
 TEST_F(CastDialogViewTest, ClearIssue) {
   std::vector<UIMediaSink> media_sinks = {CreateAvailableSink()};
-  media_sinks[0].issue = Issue(IssueInfo("title", IssueInfo::Action::DISMISS,
-                                         IssueInfo::Severity::WARNING));
+  media_sinks[0].issue =
+      Issue(IssueInfo("title", IssueInfo::Severity::WARNING));
   CastDialogModel model = CreateModelWithSinks(std::move(media_sinks));
   InitializeDialogWithModel(model);
   // When there is an issue, clicking on an available sink should clear the
diff --git a/chrome/browser/ui/views/media_router/cast_toolbar_button_unittest.cc b/chrome/browser/ui/views/media_router/cast_toolbar_button_unittest.cc
index 06be7876..227f2bb 100644
--- a/chrome/browser/ui/views/media_router/cast_toolbar_button_unittest.cc
+++ b/chrome/browser/ui/views/media_router/cast_toolbar_button_unittest.cc
@@ -157,14 +157,12 @@
   button_->UpdateIcon();
   EXPECT_TRUE(gfx::test::AreImagesEqual(idle_icon_, GetIcon()));
 
-  button_->OnIssue(
-      Issue(IssueInfo("title notification", IssueInfo::Action::DISMISS,
-                      IssueInfo::Severity::NOTIFICATION)));
+  button_->OnIssue(Issue(
+      IssueInfo("title notification", IssueInfo::Severity::NOTIFICATION)));
   EXPECT_TRUE(gfx::test::AreImagesEqual(idle_icon_, GetIcon()));
 
   button_->OnIssue(
-      Issue(IssueInfo("title warning", IssueInfo::Action::LEARN_MORE,
-                      IssueInfo::Severity::WARNING)));
+      Issue(IssueInfo("title warning", IssueInfo::Severity::WARNING)));
   EXPECT_TRUE(gfx::test::AreImagesEqual(warning_icon_, GetIcon()));
 
   button_->OnIssuesCleared();
diff --git a/chrome/browser/ui/views/media_router/media_router_ui_browsertest.cc b/chrome/browser/ui/views/media_router/media_router_ui_browsertest.cc
index f08794a70..53c92c4 100644
--- a/chrome/browser/ui/views/media_router/media_router_ui_browsertest.cc
+++ b/chrome/browser/ui/views/media_router/media_router_ui_browsertest.cc
@@ -43,7 +43,6 @@
  public:
   MediaRouterUIBrowserTest()
       : issue_(IssueInfo("title notification",
-                         IssueInfo::Action::DISMISS,
                          IssueInfo::Severity::NOTIFICATION)) {}
   ~MediaRouterUIBrowserTest() override {}
 
diff --git a/chrome/browser/ui/views/payments/contact_info_editor_view_controller.cc b/chrome/browser/ui/views/payments/contact_info_editor_view_controller.cc
index 0462f9c..53cf55d 100644
--- a/chrome/browser/ui/views/payments/contact_info_editor_view_controller.cc
+++ b/chrome/browser/ui/views/payments/contact_info_editor_view_controller.cc
@@ -134,6 +134,11 @@
                                 IDS_PAYMENTS_ADD_CONTACT_DETAILS_LABEL);
 }
 
+base::WeakPtr<PaymentRequestSheetController>
+ContactInfoEditorViewController::GetWeakPtr() {
+  return weak_ptr_factory_.GetWeakPtr();
+}
+
 void ContactInfoEditorViewController::PopulateProfile(
     autofill::AutofillProfile* profile) {
   for (const auto& field : text_fields()) {
diff --git a/chrome/browser/ui/views/payments/contact_info_editor_view_controller.h b/chrome/browser/ui/views/payments/contact_info_editor_view_controller.h
index 2e52a1a..09080004 100644
--- a/chrome/browser/ui/views/payments/contact_info_editor_view_controller.h
+++ b/chrome/browser/ui/views/payments/contact_info_editor_view_controller.h
@@ -50,6 +50,7 @@
  protected:
   // PaymentRequestSheetController:
   std::u16string GetSheetTitle() override;
+  base::WeakPtr<PaymentRequestSheetController> GetWeakPtr() override;
 
  private:
   // Uses the values in the UI fields to populate the corresponding values in
@@ -95,6 +96,9 @@
     raw_ptr<ContactInfoEditorViewController, DanglingUntriaged> controller_;
     const raw_ref<const std::string> locale_;
   };
+
+  // Must be the last member of a leaf class.
+  base::WeakPtrFactory<ContactInfoEditorViewController> weak_ptr_factory_{this};
 };
 
 }  // namespace payments
diff --git a/chrome/browser/ui/views/payments/error_message_view_controller.cc b/chrome/browser/ui/views/payments/error_message_view_controller.cc
index a64e6d8..e1e40f9 100644
--- a/chrome/browser/ui/views/payments/error_message_view_controller.cc
+++ b/chrome/browser/ui/views/payments/error_message_view_controller.cc
@@ -102,4 +102,9 @@
   return true;
 }
 
+base::WeakPtr<PaymentRequestSheetController>
+ErrorMessageViewController::GetWeakPtr() {
+  return weak_ptr_factory_.GetWeakPtr();
+}
+
 }  // namespace payments
diff --git a/chrome/browser/ui/views/payments/error_message_view_controller.h b/chrome/browser/ui/views/payments/error_message_view_controller.h
index 67e14815..5aa7ec2 100644
--- a/chrome/browser/ui/views/payments/error_message_view_controller.h
+++ b/chrome/browser/ui/views/payments/error_message_view_controller.h
@@ -46,6 +46,10 @@
   void FillContentView(views::View* content_view) override;
   bool GetSheetId(DialogViewID* sheet_id) override;
   bool ShouldAccelerateEnterKey() override;
+  base::WeakPtr<PaymentRequestSheetController> GetWeakPtr() override;
+
+  // Must be the last member of a leaf class.
+  base::WeakPtrFactory<ErrorMessageViewController> weak_ptr_factory_{this};
 };
 
 }  // namespace payments
diff --git a/chrome/browser/ui/views/payments/order_summary_view_controller.cc b/chrome/browser/ui/views/payments/order_summary_view_controller.cc
index 41170d6..8517dfd4 100644
--- a/chrome/browser/ui/views/payments/order_summary_view_controller.cc
+++ b/chrome/browser/ui/views/payments/order_summary_view_controller.cc
@@ -218,4 +218,9 @@
   return true;
 }
 
+base::WeakPtr<PaymentRequestSheetController>
+OrderSummaryViewController::GetWeakPtr() {
+  return weak_ptr_factory_.GetWeakPtr();
+}
+
 }  // namespace payments
diff --git a/chrome/browser/ui/views/payments/order_summary_view_controller.h b/chrome/browser/ui/views/payments/order_summary_view_controller.h
index 61b7226..205bb49 100644
--- a/chrome/browser/ui/views/payments/order_summary_view_controller.h
+++ b/chrome/browser/ui/views/payments/order_summary_view_controller.h
@@ -46,6 +46,7 @@
   void FillContentView(views::View* content_view) override;
   bool GetSheetId(DialogViewID* sheet_id) override;
   bool ShouldAccelerateEnterKey() override;
+  base::WeakPtr<PaymentRequestSheetController> GetWeakPtr() override;
 
   base::WeakPtrFactory<OrderSummaryViewController> weak_ptr_factory_{this};
 };
diff --git a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc
index 3d65640..b4f135c 100644
--- a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc
+++ b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc
@@ -432,6 +432,11 @@
   return false;
 }
 
+base::WeakPtr<PaymentRequestSheetController>
+PaymentHandlerWebFlowViewController::GetWeakPtr() {
+  return weak_ptr_factory_.GetWeakPtr();
+}
+
 void PaymentHandlerWebFlowViewController::VisibleSecurityStateChanged(
     content::WebContents* source) {
   DCHECK_EQ(source, web_contents());
diff --git a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.h b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.h
index 0e85bb7..d8a64f7 100644
--- a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.h
+++ b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.h
@@ -71,6 +71,7 @@
       views::View* header_view) override;
   bool GetSheetId(DialogViewID* sheet_id) override;
   bool DisplayDynamicBorderForHiddenContents() override;
+  base::WeakPtr<PaymentRequestSheetController> GetWeakPtr() override;
 
   // content::WebContentsDelegate:
   void VisibleSecurityStateChanged(content::WebContents* source) override;
@@ -105,6 +106,10 @@
   // A handler to handle unhandled keyboard messages coming back from the
   // renderer process.
   views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_;
+
+  // Must be the last member of a leaf class.
+  base::WeakPtrFactory<PaymentHandlerWebFlowViewController> weak_ptr_factory_{
+      this};
 };
 
 }  // namespace payments
diff --git a/chrome/browser/ui/views/payments/payment_method_view_controller.cc b/chrome/browser/ui/views/payments/payment_method_view_controller.cc
index 29dcab2fb..dd733e1 100644
--- a/chrome/browser/ui/views/payments/payment_method_view_controller.cc
+++ b/chrome/browser/ui/views/payments/payment_method_view_controller.cc
@@ -197,4 +197,9 @@
   return static_cast<int>(DialogViewID::PAYMENT_METHOD_ADD_CARD_BUTTON);
 }
 
+base::WeakPtr<PaymentRequestSheetController>
+PaymentMethodViewController::GetWeakPtr() {
+  return weak_ptr_factory_.GetWeakPtr();
+}
+
 }  // namespace payments
diff --git a/chrome/browser/ui/views/payments/payment_method_view_controller.h b/chrome/browser/ui/views/payments/payment_method_view_controller.h
index c87b6e17..56d8c51 100644
--- a/chrome/browser/ui/views/payments/payment_method_view_controller.h
+++ b/chrome/browser/ui/views/payments/payment_method_view_controller.h
@@ -37,8 +37,12 @@
   bool ShouldShowSecondaryButton() override;
   std::u16string GetSecondaryButtonLabel() override;
   int GetSecondaryButtonId() override;
+  base::WeakPtr<PaymentRequestSheetController> GetWeakPtr() override;
 
   PaymentRequestItemList payment_method_list_;
+
+  // Must be the last member of a leaf class.
+  base::WeakPtrFactory<PaymentMethodViewController> weak_ptr_factory_{this};
 };
 
 }  // namespace payments
diff --git a/chrome/browser/ui/views/payments/payment_request_browsertest_base.cc b/chrome/browser/ui/views/payments/payment_request_browsertest_base.cc
index 7a3adb3..19b240e9 100644
--- a/chrome/browser/ui/views/payments/payment_request_browsertest_base.cc
+++ b/chrome/browser/ui/views/payments/payment_request_browsertest_base.cc
@@ -52,6 +52,7 @@
 #include "ui/views/controls/button/md_text_button.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/controls/styled_label.h"
+#include "ui/views/input_event_activation_protector.h"
 
 namespace payments {
 
@@ -113,6 +114,10 @@
 
   // Register all prefs with our pref testing service.
   payments::RegisterProfilePrefs(prefs_.registry());
+
+  // Clicks from tests should always be allowed, even on dialogs that have
+  // protection against accidental double-clicking/etc.
+  views::InputEventActivationProtector::DisableForTesting();
 }
 
 void PaymentRequestBrowserTestBase::NavigateTo(const std::string& file_path) {
@@ -168,6 +173,8 @@
 
 void PaymentRequestBrowserTestBase::OnConnectionTerminated() {}
 
+void PaymentRequestBrowserTestBase::OnPayCalled() {}
+
 void PaymentRequestBrowserTestBase::OnAbortCalled() {
   if (event_waiter_)
     event_waiter_->OnEvent(DialogEvent::ABORT_CALLED);
@@ -567,6 +574,14 @@
     views::View* view,
     PaymentRequestDialogView* dialog_view,
     bool wait_for_animation) {
+  ClickOnDialogView(view);
+  if (wait_for_animation) {
+    WaitForAnimation(dialog_view);
+  }
+  WaitForObservedEvent();
+}
+
+void PaymentRequestBrowserTestBase::ClickOnDialogView(views::View* view) {
   DCHECK(view);
   ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
                          ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
@@ -576,11 +591,6 @@
       ui::ET_MOUSE_RELEASED, gfx::Point(), gfx::Point(), ui::EventTimeForNow(),
       ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
   view->OnMouseReleased(released_event);
-
-  if (wait_for_animation)
-    WaitForAnimation(dialog_view);
-
-  WaitForObservedEvent();
 }
 
 void PaymentRequestBrowserTestBase::ClickOnChildInListViewAndWait(
diff --git a/chrome/browser/ui/views/payments/payment_request_browsertest_base.h b/chrome/browser/ui/views/payments/payment_request_browsertest_base.h
index ac4ccc0..a012ddf 100644
--- a/chrome/browser/ui/views/payments/payment_request_browsertest_base.h
+++ b/chrome/browser/ui/views/payments/payment_request_browsertest_base.h
@@ -125,6 +125,7 @@
   void OnHasEnrolledInstrumentReturned() override;
   void OnNotSupportedError() override;
   void OnConnectionTerminated() override;
+  void OnPayCalled() override;
   void OnAbortCalled() override;
 
   // PaymentRequestDialogView::ObserverForTest:
@@ -211,6 +212,12 @@
                                      size_t total_num_children,
                                      DialogViewID list_view_id,
                                      bool wait_for_animation = true);
+
+  // Click on a view from within the dialog. Does NOT wait for asynchronous
+  // effects including any animation. Most use-cases should use
+  // ClickOnDialogViewAndWait instead.
+  void ClickOnDialogView(views::View* view);
+
   // Returns profile label values under |parent_view|.
   std::vector<std::u16string> GetProfileLabelValues(
       DialogViewID parent_view_id);
diff --git a/chrome/browser/ui/views/payments/payment_request_sheet_controller.cc b/chrome/browser/ui/views/payments/payment_request_sheet_controller.cc
index b3da85f..e859630a 100644
--- a/chrome/browser/ui/views/payments/payment_request_sheet_controller.cc
+++ b/chrome/browser/ui/views/payments/payment_request_sheet_controller.cc
@@ -50,8 +50,9 @@
 class SheetView : public views::BoxLayoutView, public views::FocusTraversable {
  public:
   METADATA_HEADER(SheetView);
-  explicit SheetView(const base::RepeatingCallback<void(bool*)>&
-                         enter_key_accelerator_callback)
+  explicit SheetView(
+      const base::RepeatingCallback<void(bool*, const ui::Event&)>&
+          enter_key_accelerator_callback)
       : enter_key_accelerator_callback_(enter_key_accelerator_callback) {
     if (enter_key_accelerator_callback_)
       AddAccelerator(enter_key_accelerator_);
@@ -115,7 +116,8 @@
       return views::View::AcceleratorPressed(accelerator);
 
     bool is_enabled = false;
-    enter_key_accelerator_callback_.Run(&is_enabled);
+    enter_key_accelerator_callback_.Run(&is_enabled,
+                                        enter_key_accelerator_.ToKeyEvent());
     return is_enabled;
   }
 
@@ -131,7 +133,8 @@
                                            /*cycle=*/true,
                                            /*accessibility_mode=*/false);
   ui::Accelerator enter_key_accelerator_{ui::VKEY_RETURN, ui::EF_NONE};
-  base::RepeatingCallback<void(bool*)> enter_key_accelerator_callback_;
+  base::RepeatingCallback<void(bool*, const ui::Event&)>
+      enter_key_accelerator_callback_;
 };
 
 BEGIN_METADATA(SheetView, views::BoxLayoutView)
@@ -262,8 +265,8 @@
               ShouldAccelerateEnterKey()
                   ? base::BindRepeating(&PaymentRequestSheetController::
                                             PerformPrimaryButtonAction,
-                                        weak_ptr_factory_.GetWeakPtr())
-                  : base::RepeatingCallback<void(bool*)>()))
+                                        GetWeakPtr())
+                  : base::RepeatingCallback<void(bool*, const ui::Event&)>()))
           .SetOrientation(views::BoxLayout::Orientation::kVertical)
           .CustomConfigure(base::BindOnce(
               [](PaymentRequestSheetController* controller,
@@ -588,7 +591,8 @@
 }
 
 void PaymentRequestSheetController::PerformPrimaryButtonAction(
-    bool* is_enabled) {
+    bool* is_enabled,
+    const ui::Event& event) {
   // Set |is_enabled| to "true" to prevent other views from handling the event.
   *is_enabled = true;
 
@@ -596,7 +600,7 @@
       primary_button_->GetEnabled()) {
     ButtonCallback callback = GetPrimaryButtonCallback();
     if (callback)
-      callback.Run();
+      callback.Run(event);
   }
 }
 
diff --git a/chrome/browser/ui/views/payments/payment_request_sheet_controller.h b/chrome/browser/ui/views/payments/payment_request_sheet_controller.h
index 2b85084..fb966d1 100644
--- a/chrome/browser/ui/views/payments/payment_request_sheet_controller.h
+++ b/chrome/browser/ui/views/payments/payment_request_sheet_controller.h
@@ -27,7 +27,7 @@
 // views shown in the PaymentRequestDialog.
 class PaymentRequestSheetController {
  public:
-  using ButtonCallback = base::RepeatingClosure;
+  using ButtonCallback = views::Button::PressedCallback;
 
   // Objects of this class are owned by |dialog|, so it's a non-owned pointer
   // that should be valid throughout this object's lifetime.
@@ -199,9 +199,11 @@
   // Returns whether the controller should be controlling the UI.
   bool is_active() const { return is_active_; }
 
-  base::WeakPtr<PaymentRequestSheetController> GetWeakPtr() {
-    return weak_ptr_factory_.GetWeakPtr();
-  }
+  // Provide a base::WeakPtr to the subclass instance. Subclasses must implement
+  // this method as a base::WeakPtrFactory must be the last member in the
+  // concrete (aka leaf) class in order to avoid subtle use-after-destroy
+  // issues.
+  virtual base::WeakPtr<PaymentRequestSheetController> GetWeakPtr() = 0;
 
  private:
   // Add the primary/secondary buttons to |container|.
@@ -213,7 +215,7 @@
   // otherwise sets it to false. The |is_enabled| is an out-param to enable
   // binding the method with a base::WeakPtr, which prohibits non-void return
   // values.
-  void PerformPrimaryButtonAction(bool* is_enabled);
+  void PerformPrimaryButtonAction(bool* is_enabled, const ui::Event& event);
 
   base::WeakPtr<PaymentRequestSpec> const spec_;
   base::WeakPtr<PaymentRequestState> const state_;
@@ -237,8 +239,6 @@
 
   // Whether the controller should be controlling the UI.
   bool is_active_ = true;
-
-  base::WeakPtrFactory<PaymentRequestSheetController> weak_ptr_factory_{this};
 };
 
 }  // namespace payments
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
index 16bab4c..af41a6c 100644
--- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
+++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
@@ -347,11 +347,19 @@
     base::WeakPtr<PaymentRequestSpec> spec,
     base::WeakPtr<PaymentRequestState> state,
     base::WeakPtr<PaymentRequestDialogView> dialog)
-    : PaymentRequestSheetController(spec, state, dialog) {
+    : PaymentRequestSheetController(spec, state, dialog),
+      input_protector_(
+          std::make_unique<views::InputEventActivationProtector>()) {
   DCHECK(spec);
   DCHECK(state);
   spec->AddObserver(this);
   state->AddObserver(this);
+
+  // This class is constructed as the view is being shown, so we mark it as
+  // visible now. The view may become hidden again in the future (if the user
+  // clicks into a sub-view), but we only need to defend the initial showing
+  // against acccidental clicks on [Continue] and so this location suffices.
+  input_protector_->VisibilityChanged(/*is_visible=*/true);
 }
 
 PaymentSheetViewController::~PaymentSheetViewController() {
@@ -383,6 +391,15 @@
   }
 }
 
+PaymentRequestSheetController::ButtonCallback
+PaymentSheetViewController::GetPrimaryButtonCallback() {
+  PaymentRequestSheetController::ButtonCallback parent_callback =
+      PaymentRequestSheetController::GetPrimaryButtonCallback();
+  return base::BindRepeating(
+      &PaymentSheetViewController::PossiblyIgnorePrimaryButtonPress,
+      weak_ptr_factory_.GetWeakPtr(), std::move(parent_callback));
+}
+
 std::u16string PaymentSheetViewController::GetSecondaryButtonLabel() {
   return l10n_util::GetStringUTF16(IDS_CANCEL);
 }
@@ -468,6 +485,11 @@
   return true;
 }
 
+base::WeakPtr<PaymentRequestSheetController>
+PaymentSheetViewController::GetWeakPtr() {
+  return weak_ptr_factory_.GetWeakPtr();
+}
+
 // Creates the Order Summary row, which contains an "Order Summary" label,
 // an inline list of display items, a Total Amount label, and a Chevron. Returns
 // nullptr if WeakPtr<PaymentRequestSpec> has become null.
@@ -898,4 +920,13 @@
       nullptr);
 }
 
+void PaymentSheetViewController::PossiblyIgnorePrimaryButtonPress(
+    PaymentRequestSheetController::ButtonCallback callback,
+    const ui::Event& event) {
+  if (input_protector_->IsPossiblyUnintendedInteraction(event)) {
+    return;
+  }
+  callback.Run(event);
+}
+
 }  // namespace payments
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller.h b/chrome/browser/ui/views/payments/payment_sheet_view_controller.h
index 19320617..7605991 100644
--- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.h
+++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.h
@@ -6,11 +6,13 @@
 #define CHROME_BROWSER_UI_VIEWS_PAYMENTS_PAYMENT_SHEET_VIEW_CONTROLLER_H_
 
 #include <memory>
+#include <utility>
 
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/ui/views/payments/payment_request_sheet_controller.h"
 #include "components/payments/content/payment_request_spec.h"
 #include "components/payments/content/payment_request_state.h"
+#include "ui/views/input_event_activation_protector.h"
 
 namespace payments {
 
@@ -44,14 +46,21 @@
 
   void ButtonPressed(base::RepeatingClosure closure);
 
+  void SetInputEventActivationProtectorForTesting(
+      std::unique_ptr<views::InputEventActivationProtector> input_protector) {
+    input_protector_ = std::move(input_protector);
+  }
+
  private:
   // PaymentRequestSheetController:
+  ButtonCallback GetPrimaryButtonCallback() override;
   std::u16string GetSecondaryButtonLabel() override;
   bool ShouldShowHeaderBackArrow() override;
   std::u16string GetSheetTitle() override;
   void FillContentView(views::View* content_view) override;
   std::unique_ptr<views::View> CreateExtraFooterView() override;
   bool GetSheetId(DialogViewID* sheet_id) override;
+  base::WeakPtr<PaymentRequestSheetController> GetWeakPtr() override;
 
   // These functions create the various sections and rows of the payment sheet.
   // Where applicable, they also populate |accessible_content|, which shouldn't
@@ -69,6 +78,16 @@
 
   void AddShippingButtonPressed();
   void AddContactInfoButtonPressed();
+
+  // Used to mitigate against accidental clicks on the primary button if a user
+  // e.g., double-clicks on a web-content button that then launches
+  // PaymentRequest. See https://crbug.com/1403493
+  void PossiblyIgnorePrimaryButtonPress(ButtonCallback callback,
+                                        const ui::Event& event);
+  std::unique_ptr<views::InputEventActivationProtector> input_protector_;
+
+  // Must be the last member of a leaf class.
+  base::WeakPtrFactory<PaymentSheetViewController> weak_ptr_factory_{this};
 };
 
 }  // namespace payments
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller_browsertest.cc b/chrome/browser/ui/views/payments/payment_sheet_view_controller_browsertest.cc
index 54dc94d..b9ca7a9 100644
--- a/chrome/browser/ui/views/payments/payment_sheet_view_controller_browsertest.cc
+++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller_browsertest.cc
@@ -5,6 +5,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/ui/views/payments/payment_request_browsertest_base.h"
 #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h"
+#include "chrome/browser/ui/views/payments/payment_sheet_view_controller.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/autofill/core/browser/autofill_test_utils.h"
 #include "components/autofill/core/browser/data_model/autofill_profile.h"
@@ -16,10 +17,67 @@
 #include "net/dns/mock_host_resolver.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/views/test/mock_input_event_activation_protector.h"
 
 namespace payments {
 
-using PaymentSheetViewControllerTest = PaymentRequestBrowserTestBase;
+class PaymentSheetViewControllerTest : public PaymentRequestBrowserTestBase {
+ public:
+  PaymentSheetViewControllerTest() = default;
+  ~PaymentSheetViewControllerTest() override = default;
+
+  void OnPayCalled() override { pay_was_called_ = true; }
+
+ protected:
+  bool pay_was_called_ = false;
+};
+
+// The [Continue] button should be protected against accidental double-inputs.
+IN_PROC_BROWSER_TEST_F(PaymentSheetViewControllerTest,
+                       ContinueButtonIgnoresAccidentalInputs) {
+  // Installs two apps so that the Payment Request UI will be shown.
+  std::string a_method_name;
+  InstallPaymentApp("a.com", "/payment_request_success_responder.js",
+                    &a_method_name);
+  std::string b_method_name;
+  InstallPaymentApp("b.com", "/payment_request_success_responder.js",
+                    &b_method_name);
+
+  NavigateTo("/payment_request_no_shipping_test.html");
+  InvokePaymentRequestUIWithJs(content::JsReplace(
+      "buyWithMethods([{supportedMethods:$1}, {supportedMethods:$2}]);",
+      a_method_name, b_method_name));
+
+  ASSERT_TRUE(IsViewVisible(DialogViewID::PAY_BUTTON));
+  ASSERT_TRUE(IsViewVisible(DialogViewID::CANCEL_BUTTON));
+  ASSERT_TRUE(IsPayButtonEnabled());
+  ASSERT_FALSE(pay_was_called_);
+
+  // Set up a mock input protector, which ignores the first input and then
+  // accepts all subsequent inputs.
+  auto input_protector =
+      std::make_unique<views::MockInputEventActivationProtector>();
+  EXPECT_CALL(*input_protector, IsPossiblyUnintendedInteraction)
+      .WillOnce(testing::Return(true))
+      .WillRepeatedly(testing::Return(false));
+
+  views::View* sheet_view = dialog_view()->GetViewByID(
+      static_cast<int>(DialogViewID::PAYMENT_REQUEST_SHEET));
+  static_cast<PaymentSheetViewController*>(
+      dialog_view()->controller_map_for_testing()->at(sheet_view).get())
+      ->SetInputEventActivationProtectorForTesting(std::move(input_protector));
+
+  // Because of the input protector, the first press of the button should be
+  // ignored.
+  views::View* button_view =
+      dialog_view()->GetViewByID(static_cast<int>(DialogViewID::PAY_BUTTON));
+  ClickOnDialogView(button_view);
+  EXPECT_FALSE(pay_was_called_);
+
+  // However a subsequent press should result in Pay() being called.
+  ClickOnDialogView(button_view);
+  EXPECT_TRUE(pay_was_called_);
+}
 
 // The 'Continue' or 'Cancel' buttons should not be auto-focused; see
 // https://crbug.com/1403539
diff --git a/chrome/browser/ui/views/payments/profile_list_view_controller.cc b/chrome/browser/ui/views/payments/profile_list_view_controller.cc
index b7c879e..7f3cc30 100644
--- a/chrome/browser/ui/views/payments/profile_list_view_controller.cc
+++ b/chrome/browser/ui/views/payments/profile_list_view_controller.cc
@@ -387,4 +387,9 @@
   content_view->AddChildView(list_view.release());
 }
 
+base::WeakPtr<PaymentRequestSheetController>
+ProfileListViewController::GetWeakPtr() {
+  return weak_ptr_factory_.GetWeakPtr();
+}
+
 }  // namespace payments
diff --git a/chrome/browser/ui/views/payments/profile_list_view_controller.h b/chrome/browser/ui/views/payments/profile_list_view_controller.h
index 5e5a31f..a18aec8 100644
--- a/chrome/browser/ui/views/payments/profile_list_view_controller.h
+++ b/chrome/browser/ui/views/payments/profile_list_view_controller.h
@@ -96,11 +96,13 @@
   bool ShouldShowPrimaryButton() override;
   ButtonCallback GetSecondaryButtonCallback() override;
   void FillContentView(views::View* content_view) override;
+  base::WeakPtr<PaymentRequestSheetController> GetWeakPtr() override;
 
  private:
   std::unique_ptr<views::Button> CreateRow(autofill::AutofillProfile* profile);
   PaymentRequestItemList list_;
 
+  // Must be the last member of a leaf class.
   base::WeakPtrFactory<ProfileListViewController> weak_ptr_factory_{this};
 };
 
diff --git a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc
index 341fae7c..5924aa76 100644
--- a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc
+++ b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc
@@ -214,6 +214,11 @@
                           : l10n_util::GetStringUTF16(IDS_PAYMENTS_ADD_ADDRESS);
 }
 
+base::WeakPtr<PaymentRequestSheetController>
+ShippingAddressEditorViewController::GetWeakPtr() {
+  return weak_ptr_factory_.GetWeakPtr();
+}
+
 int ShippingAddressEditorViewController::GetPrimaryButtonId() {
   return static_cast<int>(DialogViewID::SAVE_ADDRESS_BUTTON);
 }
diff --git a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.h b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.h
index 81dac186..0ff312a 100644
--- a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.h
+++ b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.h
@@ -67,6 +67,7 @@
 
   // PaymentRequestSheetController:
   std::u16string GetSheetTitle() override;
+  base::WeakPtr<PaymentRequestSheetController> GetWeakPtr() override;
 
  protected:
   int GetPrimaryButtonId() override;
@@ -173,6 +174,7 @@
   // Owned by the state combobox, which is owned by this object's base class.
   raw_ptr<autofill::RegionComboboxModel, DanglingUntriaged> region_model_;
 
+  // Must be the last member of a leaf class.
   base::WeakPtrFactory<ShippingAddressEditorViewController> weak_ptr_factory_{
       this};
 };
diff --git a/chrome/browser/ui/views/payments/shipping_option_view_controller.cc b/chrome/browser/ui/views/payments/shipping_option_view_controller.cc
index 4c5ba38..c0c4107 100644
--- a/chrome/browser/ui/views/payments/shipping_option_view_controller.cc
+++ b/chrome/browser/ui/views/payments/shipping_option_view_controller.cc
@@ -141,4 +141,9 @@
   return false;
 }
 
+base::WeakPtr<PaymentRequestSheetController>
+ShippingOptionViewController::GetWeakPtr() {
+  return weak_ptr_factory_.GetWeakPtr();
+}
+
 }  // namespace payments
diff --git a/chrome/browser/ui/views/payments/shipping_option_view_controller.h b/chrome/browser/ui/views/payments/shipping_option_view_controller.h
index 63c99f16..10ded8a 100644
--- a/chrome/browser/ui/views/payments/shipping_option_view_controller.h
+++ b/chrome/browser/ui/views/payments/shipping_option_view_controller.h
@@ -37,9 +37,11 @@
   std::unique_ptr<views::View> CreateExtraFooterView() override;
   bool ShouldShowPrimaryButton() override;
   bool ShouldShowSecondaryButton() override;
+  base::WeakPtr<PaymentRequestSheetController> GetWeakPtr() override;
 
   PaymentRequestItemList shipping_option_list_;
 
+  // Must be the last member of a leaf class.
   base::WeakPtrFactory<ShippingOptionViewController> weak_ptr_factory_{this};
 };
 
diff --git a/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_browsertest.cc b/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_browsertest.cc
index fdf1300..7a6d132 100644
--- a/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_browsertest.cc
+++ b/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_browsertest.cc
@@ -131,7 +131,7 @@
   }
 
   SidePanelRegistry* global_registry() {
-    return side_panel_coordinator()->GetGlobalSidePanelRegistry();
+    return SidePanelCoordinator::GetGlobalSidePanelRegistry(browser());
   }
 
   SidePanelCoordinator* side_panel_coordinator() {
@@ -231,9 +231,7 @@
   // registered for the new window's global SidePanelRegistry.
   Browser* second_browser = CreateBrowser(browser()->profile());
   SidePanelRegistry* second_global_registry =
-      BrowserView::GetBrowserViewForBrowser(second_browser)
-          ->side_panel_coordinator()
-          ->GetGlobalSidePanelRegistry();
+      SidePanelCoordinator::GetGlobalSidePanelRegistry(second_browser);
   EXPECT_TRUE(second_global_registry->GetEntryForKey(extension_key));
 }
 
@@ -426,9 +424,7 @@
 
  protected:
   SidePanelRegistry* global_registry() {
-    return BrowserView::GetBrowserViewForBrowser(browser())
-        ->side_panel_coordinator()
-        ->GetGlobalSidePanelRegistry();
+    return SidePanelCoordinator::GetGlobalSidePanelRegistry(browser());
   }
 
  private:
diff --git a/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_coordinator.cc b/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_coordinator.cc
index 5e00387..e0bd919 100644
--- a/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_coordinator.cc
+++ b/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_coordinator.cc
@@ -8,7 +8,6 @@
 #include "chrome/browser/extensions/extension_view_host_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
-#include "chrome/browser/ui/views/side_panel/extensions/extension_side_panel_utils.h"
 #include "chrome/browser/ui/views/side_panel/side_panel_coordinator.h"
 #include "chrome/browser/ui/views/side_panel/side_panel_registry.h"
 #include "chrome/common/extensions/api/side_panel.h"
@@ -67,7 +66,8 @@
 }
 
 void ExtensionSidePanelCoordinator::DeregisterGlobalEntry() {
-  if (auto* global_registry = GetGlobalSidePanelRegistry(browser_)) {
+  if (auto* global_registry =
+          SidePanelCoordinator::GetGlobalSidePanelRegistry(browser_)) {
     global_registry->Deregister(GetEntryKey());
   }
 }
@@ -97,7 +97,8 @@
     return;
   }
 
-  SidePanelRegistry* global_registry = GetGlobalSidePanelRegistry(browser_);
+  SidePanelRegistry* global_registry =
+      SidePanelCoordinator::GetGlobalSidePanelRegistry(browser_);
   if (!global_registry) {
     return;
   }
@@ -145,7 +146,8 @@
   // If the SidePanelEntry exists for this extension, update its icon.
   // TODO(crbug.com/1378048): Update the icon for all extension entries in
   // contextual registries.
-  if (auto* global_registry = GetGlobalSidePanelRegistry(browser_)) {
+  if (auto* global_registry =
+          SidePanelCoordinator::GetGlobalSidePanelRegistry(browser_)) {
     if (SidePanelEntry* entry =
             global_registry->GetEntryForKey(GetEntryKey())) {
       entry->ResetIcon(ui::ImageModel::FromImage(updated_icon->image()));
diff --git a/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_manager.cc b/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_manager.cc
index 46840cd..addf510 100644
--- a/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_manager.cc
+++ b/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_manager.cc
@@ -6,7 +6,7 @@
 
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/views/side_panel/extensions/extension_side_panel_utils.h"
+#include "chrome/browser/ui/views/side_panel/side_panel_coordinator.h"
 #include "chrome/browser/ui/views/side_panel/side_panel_registry.h"
 #include "chrome/common/extensions/api/side_panel/side_panel_info.h"
 #include "content/public/browser/browser_context.h"
@@ -44,7 +44,7 @@
     content::BrowserContext* browser_context,
     const Extension* extension) {
   MaybeCreateExtensionSidePanelCoordinator(
-      extension, GetGlobalSidePanelRegistry(browser_));
+      extension, SidePanelCoordinator::GetGlobalSidePanelRegistry(browser_));
 }
 
 void ExtensionSidePanelManager::OnExtensionUnloaded(
diff --git a/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_utils.cc b/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_utils.cc
deleted file mode 100644
index 8a8ee141..0000000
--- a/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_utils.cc
+++ /dev/null
@@ -1,24 +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.
-
-#include "chrome/browser/ui/views/side_panel/extensions/extension_side_panel_utils.h"
-
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/views/frame/browser_view.h"
-#include "chrome/browser/ui/views/side_panel/side_panel_coordinator.h"
-#include "chrome/browser/ui/views/side_panel/side_panel_registry.h"
-
-namespace extensions {
-
-SidePanelRegistry* GetGlobalSidePanelRegistry(Browser* browser) {
-  BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
-  if (!browser_view) {
-    return nullptr;
-  }
-
-  SidePanelCoordinator* coordinator = browser_view->side_panel_coordinator();
-  return coordinator ? coordinator->GetGlobalSidePanelRegistry() : nullptr;
-}
-
-}  // namespace extensions
diff --git a/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_utils.h b/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_utils.h
deleted file mode 100644
index 4fc8de5..0000000
--- a/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_utils.h
+++ /dev/null
@@ -1,19 +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.
-
-#ifndef CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_EXTENSIONS_EXTENSION_SIDE_PANEL_UTILS_H_
-#define CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_EXTENSIONS_EXTENSION_SIDE_PANEL_UTILS_H_
-
-class Browser;
-class SidePanelRegistry;
-
-namespace extensions {
-
-// Returns the global side panel registry for this browser. This must be called
-// after the browser's BrowserView has been created.
-SidePanelRegistry* GetGlobalSidePanelRegistry(Browser* browser);
-
-}  // namespace extensions
-
-#endif  // CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_EXTENSIONS_EXTENSION_SIDE_PANEL_UTILS_H_
diff --git a/chrome/browser/ui/views/side_panel/history_clusters/history_clusters_side_panel_coordinator.cc b/chrome/browser/ui/views/side_panel/history_clusters/history_clusters_side_panel_coordinator.cc
index 04277f1..c11fdcb 100644
--- a/chrome/browser/ui/views/side_panel/history_clusters/history_clusters_side_panel_coordinator.cc
+++ b/chrome/browser/ui/views/side_panel/history_clusters/history_clusters_side_panel_coordinator.cc
@@ -112,9 +112,8 @@
 
 void HistoryClustersSidePanelCoordinator::OnHistoryClustersPreferenceChanged() {
   auto* browser = &GetBrowser();
-  auto* global_registry = BrowserView::GetBrowserViewForBrowser(browser)
-                              ->side_panel_coordinator()
-                              ->GetGlobalSidePanelRegistry();
+  auto* global_registry =
+      SidePanelCoordinator::GetGlobalSidePanelRegistry(browser);
   if (browser->profile()->GetPrefs()->GetBoolean(
           history_clusters::prefs::kVisible)) {
     if (IsSupported(browser->profile())) {
diff --git a/chrome/browser/ui/views/side_panel/lens/lens_side_panel_coordinator.cc b/chrome/browser/ui/views/side_panel/lens/lens_side_panel_coordinator.cc
index 3d68305..ecd955b 100644
--- a/chrome/browser/ui/views/side_panel/lens/lens_side_panel_coordinator.cc
+++ b/chrome/browser/ui/views/side_panel/lens/lens_side_panel_coordinator.cc
@@ -65,9 +65,7 @@
 
 void LensSidePanelCoordinator::DeregisterLensFromSidePanel() {
   lens_side_panel_view_ = nullptr;
-  GetBrowserView()
-      ->side_panel_coordinator()
-      ->GetGlobalSidePanelRegistry()
+  SidePanelCoordinator::GetGlobalSidePanelRegistry(&GetBrowser())
       ->Deregister(SidePanelEntry::Key(SidePanelEntry::Id::kLens));
 }
 
@@ -78,11 +76,8 @@
 }
 
 void LensSidePanelCoordinator::OnFaviconFetched(const gfx::Image& favicon) {
-  auto* side_panel_coordinator = GetBrowserView()->side_panel_coordinator();
-  if (side_panel_coordinator == nullptr)
-    return;
-
-  auto* global_registry = side_panel_coordinator->GetGlobalSidePanelRegistry();
+  auto* global_registry =
+      SidePanelCoordinator::GetGlobalSidePanelRegistry(&GetBrowser());
   if (global_registry == nullptr)
     return;
 
@@ -171,8 +166,8 @@
 void LensSidePanelCoordinator::RegisterEntryAndShow(
     const content::OpenURLParams& params) {
   base::RecordAction(base::UserMetricsAction("LensUnifiedSidePanel.LensQuery"));
-  auto* side_panel_coordinator = GetBrowserView()->side_panel_coordinator();
-  auto* global_registry = side_panel_coordinator->GetGlobalSidePanelRegistry();
+  auto* global_registry =
+      SidePanelCoordinator::GetGlobalSidePanelRegistry(&GetBrowser());
 
   // check if the view is already registered
   if (global_registry->GetEntryForKey(
@@ -195,6 +190,7 @@
     global_registry->Register(std::move(entry));
   }
 
+  auto* side_panel_coordinator = GetBrowserView()->side_panel_coordinator();
   if (side_panel_coordinator->GetCurrentEntryId() !=
       SidePanelEntry::Id::kLens) {
     if (!side_panel_coordinator->IsSidePanelShowing()) {
diff --git a/chrome/browser/ui/views/side_panel/lens/lens_side_panel_coordinator_browsertest.cc b/chrome/browser/ui/views/side_panel/lens/lens_side_panel_coordinator_browsertest.cc
index 7494044dd..a6fe6b2 100644
--- a/chrome/browser/ui/views/side_panel/lens/lens_side_panel_coordinator_browsertest.cc
+++ b/chrome/browser/ui/views/side_panel/lens/lens_side_panel_coordinator_browsertest.cc
@@ -311,8 +311,8 @@
       GetSidePanelCoordinator()->GetCurrentSidePanelEntryForTesting();
   EXPECT_EQ(last_active_entry, nullptr);
   EXPECT_EQ(
-      GetSidePanelCoordinator()->GetGlobalSidePanelRegistry()->GetEntryForKey(
-          SidePanelEntry::Key(SidePanelEntry::Id::kLens)),
+      SidePanelCoordinator::GetGlobalSidePanelRegistry(browser())
+          ->GetEntryForKey(SidePanelEntry::Key(SidePanelEntry::Id::kLens)),
       nullptr);
   EXPECT_EQ(1, user_action_tester.GetActionCount(kCloseAction));
 }
diff --git a/chrome/browser/ui/views/side_panel/lens/lens_side_panel_coordinator_unittest.cc b/chrome/browser/ui/views/side_panel/lens/lens_side_panel_coordinator_unittest.cc
index d7b2f90..e68b6c7 100644
--- a/chrome/browser/ui/views/side_panel/lens/lens_side_panel_coordinator_unittest.cc
+++ b/chrome/browser/ui/views/side_panel/lens/lens_side_panel_coordinator_unittest.cc
@@ -50,7 +50,7 @@
     GetSidePanelCoordinator()->SetNoDelaysForTesting();
     auto* browser = browser_view()->browser();
     auto* global_registry =
-        GetSidePanelCoordinator()->GetGlobalSidePanelRegistry();
+        SidePanelCoordinator::GetGlobalSidePanelRegistry(browser);
     SidePanelUtil::PopulateGlobalEntries(browser, global_registry);
 
     EXPECT_EQ(global_registry->entries().size(), 2u);
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc
index c219638..8c7e5cf 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc
@@ -81,10 +81,8 @@
   BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
   if (!browser_view)
     return;
-  SidePanelCoordinator* side_panel_coordinator =
-      browser_view->side_panel_coordinator();
   SidePanelRegistry* global_registry =
-      side_panel_coordinator->GetGlobalSidePanelRegistry();
+      SidePanelCoordinator::GetGlobalSidePanelRegistry(browser);
   global_registry->Deregister(
       SidePanelEntry::Key(SidePanelEntry::Id::kReadAnything));
 }
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator_unittest.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator_unittest.cc
index c7d6d60..4db49aabe 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator_unittest.cc
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator_unittest.cc
@@ -36,7 +36,7 @@
 
     side_panel_coordinator_ = browser_view()->side_panel_coordinator();
     side_panel_registry_ =
-        side_panel_coordinator_->GetGlobalSidePanelRegistry();
+        SidePanelCoordinator::GetGlobalSidePanelRegistry(browser());
     read_anything_coordinator_ =
         ReadAnythingCoordinator::GetOrCreateForBrowser(browser());
   }
diff --git a/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc b/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc
index 041279b4..b868297 100644
--- a/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc
+++ b/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc
@@ -10,6 +10,7 @@
 #include "base/functional/callback_forward.h"
 #include "chrome/browser/feature_engagement/tracker_factory.h"
 #include "chrome/browser/themes/theme_properties.h"
+#include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_element_identifiers.h"
 #include "chrome/browser/ui/color/chrome_color_id.h"
 #include "chrome/browser/ui/views/chrome_layout_provider.h"
@@ -173,7 +174,7 @@
   browser_view_->browser()->tab_strip_model()->AddObserver(this);
 
   SidePanelUtil::PopulateGlobalEntries(browser_view->browser(),
-                                       GetGlobalSidePanelRegistry());
+                                       global_registry_);
 }
 
 SidePanelCoordinator::~SidePanelCoordinator() {
@@ -181,6 +182,13 @@
   view_state_observers_.Clear();
 }
 
+// static
+SidePanelRegistry* SidePanelCoordinator::GetGlobalSidePanelRegistry(
+    Browser* browser) {
+  return static_cast<SidePanelRegistry*>(
+      browser->GetUserData(kGlobalSidePanelRegistryKey));
+}
+
 void SidePanelCoordinator::Show(
     absl::optional<SidePanelEntry::Id> entry_id,
     absl::optional<SidePanelUtil::SidePanelOpenTrigger> open_trigger) {
@@ -329,11 +337,6 @@
   Close();
 }
 
-SidePanelRegistry* SidePanelCoordinator::GetGlobalSidePanelRegistry() {
-  return static_cast<SidePanelRegistry*>(
-      browser_view_->browser()->GetUserData(kGlobalSidePanelRegistryKey));
-}
-
 void SidePanelCoordinator::SetNoDelaysForTesting() {
   no_delays_for_testing_ = true;
 }
diff --git a/chrome/browser/ui/views/side_panel/side_panel_coordinator.h b/chrome/browser/ui/views/side_panel/side_panel_coordinator.h
index 8f7e197..2a29c2a 100644
--- a/chrome/browser/ui/views/side_panel/side_panel_coordinator.h
+++ b/chrome/browser/ui/views/side_panel/side_panel_coordinator.h
@@ -18,6 +18,7 @@
 #include "extensions/common/extension_id.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
+class Browser;
 class BrowserView;
 class SidePanelComboboxModel;
 
@@ -46,6 +47,8 @@
   SidePanelCoordinator& operator=(const SidePanelCoordinator&) = delete;
   ~SidePanelCoordinator() override;
 
+  static SidePanelRegistry* GetGlobalSidePanelRegistry(Browser* browser);
+
   void Show(absl::optional<SidePanelEntry::Id> entry_id = absl::nullopt,
             absl::optional<SidePanelUtil::SidePanelOpenTrigger> open_trigger =
                 absl::nullopt);
@@ -59,8 +62,6 @@
   // header button, when it's visible.
   void OpenInNewTab();
 
-  SidePanelRegistry* GetGlobalSidePanelRegistry();
-
   // Prevent content swapping delays from happening for testing.
   // This should be called before the side panel is first shown.
   void SetNoDelaysForTesting();
diff --git a/chrome/browser/ui/views/side_panel/side_panel_coordinator_unittest.cc b/chrome/browser/ui/views/side_panel/side_panel_coordinator_unittest.cc
index 556d14f..8facaa24 100644
--- a/chrome/browser/ui/views/side_panel/side_panel_coordinator_unittest.cc
+++ b/chrome/browser/ui/views/side_panel/side_panel_coordinator_unittest.cc
@@ -1162,7 +1162,8 @@
     AddTab(browser_view()->browser(), GURL("http://foo2.com"));
 
     coordinator_ = browser_view()->side_panel_coordinator();
-    global_registry_ = coordinator_->GetGlobalSidePanelRegistry();
+    global_registry_ = SidePanelCoordinator::GetGlobalSidePanelRegistry(
+        browser_view()->browser());
 
     // Add a kSideSearch entry to the global registry with loading content not
     // available.
diff --git a/chrome/browser/ui/views/side_panel/side_panel_util.cc b/chrome/browser/ui/views/side_panel/side_panel_util.cc
index 4625f96..ba63b1c6 100644
--- a/chrome/browser/ui/views/side_panel/side_panel_util.cc
+++ b/chrome/browser/ui/views/side_panel/side_panel_util.cc
@@ -36,6 +36,7 @@
 #endif
 
 namespace {
+
 std::string GetHistogramNameForId(SidePanelEntry::Id id) {
   static constexpr auto id_to_histogram_name_map =
       // Note: once provided the histogram name should not be changed since it
@@ -59,6 +60,7 @@
   DCHECK(i != id_to_histogram_name_map.cend());
   return {i->second};
 }
+
 }  // namespace
 
 // static
diff --git a/chrome/browser/ui/views/tabs/tab_container_impl.cc b/chrome/browser/ui/views/tabs/tab_container_impl.cc
index 8faf23f..a12ae5d 100644
--- a/chrome/browser/ui/views/tabs/tab_container_impl.cc
+++ b/chrome/browser/ui/views/tabs/tab_container_impl.cc
@@ -694,7 +694,7 @@
       // Hide underlines if they would underline an invisible tab, but don't
       // show underlines if they're hidden during a header drag session.
       if (!group_view->header()->dragging())
-        group_view->underline()->SetVisible(last_tab_visible);
+        group_view->underline()->MaybeSetVisible(last_tab_visible);
     }
     last_tab_visible = ShouldTabBeVisible(tab);
     last_tab_group = tab->closing() ? absl::nullopt : current_group;
diff --git a/chrome/browser/ui/views/tabs/tab_group_header.cc b/chrome/browser/ui/views/tabs/tab_group_header.cc
index 1376755..84956ef1 100644
--- a/chrome/browser/ui/views/tabs/tab_group_header.cc
+++ b/chrome/browser/ui/views/tabs/tab_group_header.cc
@@ -86,8 +86,10 @@
 }  // namespace
 
 TabGroupHeader::TabGroupHeader(TabSlotController& tab_slot_controller,
-                               const tab_groups::TabGroupId& group)
+                               const tab_groups::TabGroupId& group,
+                               const TabGroupStyle& style)
     : tab_slot_controller_(tab_slot_controller),
+      style_(style),
       editor_bubble_tracker_(tab_slot_controller) {
   set_group(group);
   set_context_menu_controller(this);
diff --git a/chrome/browser/ui/views/tabs/tab_group_header.h b/chrome/browser/ui/views/tabs/tab_group_header.h
index 76356d5..b642ee8 100644
--- a/chrome/browser/ui/views/tabs/tab_group_header.h
+++ b/chrome/browser/ui/views/tabs/tab_group_header.h
@@ -17,6 +17,7 @@
 #include "ui/views/widget/widget_observer.h"
 
 class TabSlotController;
+class TabGroupStyle;
 struct TabSizeInfo;
 
 namespace views {
@@ -34,7 +35,8 @@
   METADATA_HEADER(TabGroupHeader);
 
   TabGroupHeader(TabSlotController& tab_slot_controller,
-                 const tab_groups::TabGroupId& group);
+                 const tab_groups::TabGroupId& group,
+                 const TabGroupStyle& style);
   TabGroupHeader(const TabGroupHeader&) = delete;
   TabGroupHeader& operator=(const TabGroupHeader&) = delete;
   ~TabGroupHeader() override;
@@ -82,6 +84,7 @@
 
   raw_ptr<views::View> title_chip_;
   raw_ptr<views::Label> title_;
+  const raw_ref<const TabGroupStyle> style_;
 
   // Saved collapsed state for usage with activation of element tracker system.
   bool is_collapsed_;
diff --git a/chrome/browser/ui/views/tabs/tab_group_highlight.cc b/chrome/browser/ui/views/tabs/tab_group_highlight.cc
index cea1ba4..5e899daf 100644
--- a/chrome/browser/ui/views/tabs/tab_group_highlight.cc
+++ b/chrome/browser/ui/views/tabs/tab_group_highlight.cc
@@ -14,8 +14,9 @@
 #include "ui/views/view.h"
 
 TabGroupHighlight::TabGroupHighlight(TabGroupViews* tab_group_views,
-                                     const tab_groups::TabGroupId& group)
-    : tab_group_views_(tab_group_views), group_(group) {}
+                                     const tab_groups::TabGroupId& group,
+                                     const TabGroupStyle& style)
+    : tab_group_views_(tab_group_views), group_(group), style_(style) {}
 
 void TabGroupHighlight::UpdateBounds(views::View* leading_view,
                                      views::View* trailing_view) {
diff --git a/chrome/browser/ui/views/tabs/tab_group_highlight.h b/chrome/browser/ui/views/tabs/tab_group_highlight.h
index f658003..2121c1b 100644
--- a/chrome/browser/ui/views/tabs/tab_group_highlight.h
+++ b/chrome/browser/ui/views/tabs/tab_group_highlight.h
@@ -11,6 +11,7 @@
 #include "ui/views/view.h"
 
 class TabGroupViews;
+class TabGroupStyle;
 
 // View for tab group highlights in the tab strip, which indicate that a group
 // is in a selected state. There is one highlight for each group, which is
@@ -19,7 +20,8 @@
  public:
   METADATA_HEADER(TabGroupHighlight);
   TabGroupHighlight(TabGroupViews* tab_group_views,
-                    const tab_groups::TabGroupId& group);
+                    const tab_groups::TabGroupId& group,
+                    const TabGroupStyle& style);
   TabGroupHighlight(const TabGroupHighlight&) = delete;
   TabGroupHighlight& operator=(const TabGroupHighlight&) = delete;
 
@@ -35,6 +37,7 @@
 
   const raw_ptr<TabGroupViews> tab_group_views_;
   const tab_groups::TabGroupId group_;
+  const raw_ref<const TabGroupStyle> style_;
 };
 
 #endif  // CHROME_BROWSER_UI_VIEWS_TABS_TAB_GROUP_HIGHLIGHT_H_
diff --git a/chrome/browser/ui/views/tabs/tab_group_style.cc b/chrome/browser/ui/views/tabs/tab_group_style.cc
new file mode 100644
index 0000000..e87d78d2b
--- /dev/null
+++ b/chrome/browser/ui/views/tabs/tab_group_style.cc
@@ -0,0 +1,60 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/tabs/tab_group_style.h"
+#include "chrome/browser/ui/layout_constants.h"
+#include "chrome/browser/ui/views/tabs/tab.h"
+#include "chrome/browser/ui/views/tabs/tab_group_header.h"
+#include "chrome/browser/ui/views/tabs/tab_group_underline.h"
+#include "chrome/browser/ui/views/tabs/tab_group_views.h"
+#include "ui/gfx/geometry/insets.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+#include "ui/views/view.h"
+#include "ui/views/view_utils.h"
+
+TabGroupStyle::TabGroupStyle(const TabGroupViews& tab_group_views)
+    : tab_group_views_(tab_group_views) {}
+
+TabGroupStyle::~TabGroupStyle() = default;
+
+bool TabGroupStyle::TabGroupUnderlineShouldBeHidden() const {
+  return false;
+}
+
+bool TabGroupStyle::TabGroupUnderlineShouldBeHidden(
+    const views::View* const leading_view,
+    const views::View* const trailing_view) const {
+  return false;
+}
+
+ChromeRefresh2023TabGroupStyle::ChromeRefresh2023TabGroupStyle(
+    const TabGroupViews& tab_group_views)
+    : TabGroupStyle(tab_group_views) {}
+
+ChromeRefresh2023TabGroupStyle::~ChromeRefresh2023TabGroupStyle() = default;
+
+bool ChromeRefresh2023TabGroupStyle::TabGroupUnderlineShouldBeHidden() const {
+  const auto [leading_group_view, trailing_group_view] =
+      tab_group_views_->GetLeadingTrailingGroupViews();
+
+  return TabGroupUnderlineShouldBeHidden(leading_group_view,
+                                         trailing_group_view);
+}
+
+bool ChromeRefresh2023TabGroupStyle::TabGroupUnderlineShouldBeHidden(
+    const views::View* const leading_view,
+    const views::View* const trailing_view) const {
+  const TabGroupHeader* const leading_view_group_header =
+      views::AsViewClass<TabGroupHeader>(leading_view);
+  const TabGroupHeader* const trailing_view_group_header =
+      views::AsViewClass<TabGroupHeader>(trailing_view);
+
+  if (leading_view_group_header && trailing_view_group_header &&
+      leading_view_group_header == trailing_view_group_header) {
+    return true;
+  }
+
+  return false;
+}
diff --git a/chrome/browser/ui/views/tabs/tab_group_style.h b/chrome/browser/ui/views/tabs/tab_group_style.h
new file mode 100644
index 0000000..0898d26
--- /dev/null
+++ b/chrome/browser/ui/views/tabs/tab_group_style.h
@@ -0,0 +1,45 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_TABS_TAB_GROUP_STYLE_H_
+#define CHROME_BROWSER_UI_VIEWS_TABS_TAB_GROUP_STYLE_H_
+
+#include "base/memory/raw_ptr.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/views/view.h"
+
+class TabGroupViews;
+
+class TabGroupStyle {
+ public:
+  explicit TabGroupStyle(const TabGroupViews& tab_group_views);
+  TabGroupStyle(const TabGroupStyle&) = delete;
+  TabGroupStyle& operator=(const TabGroupStyle&) = delete;
+  virtual ~TabGroupStyle();
+  // returns whether the underline for the group should be hidden
+  virtual bool TabGroupUnderlineShouldBeHidden() const;
+  virtual bool TabGroupUnderlineShouldBeHidden(
+      const views::View* leading_view,
+      const views::View* trailing_view) const;
+
+ protected:
+  const raw_ref<const TabGroupViews> tab_group_views_;
+};
+
+class ChromeRefresh2023TabGroupStyle : public TabGroupStyle {
+ public:
+  explicit ChromeRefresh2023TabGroupStyle(const TabGroupViews& tab_group_views);
+  ChromeRefresh2023TabGroupStyle(const ChromeRefresh2023TabGroupStyle&) =
+      delete;
+  ChromeRefresh2023TabGroupStyle& operator=(
+      const ChromeRefresh2023TabGroupStyle&) = delete;
+  ~ChromeRefresh2023TabGroupStyle() override;
+
+  bool TabGroupUnderlineShouldBeHidden() const override;
+  bool TabGroupUnderlineShouldBeHidden(
+      const views::View* leading_view,
+      const views::View* trailing_view) const override;
+};
+
+#endif  // CHROME_BROWSER_UI_VIEWS_TABS_TAB_GROUP_STYLE_H_
diff --git a/chrome/browser/ui/views/tabs/tab_group_underline.cc b/chrome/browser/ui/views/tabs/tab_group_underline.cc
index 8d68d35..0388b2f 100644
--- a/chrome/browser/ui/views/tabs/tab_group_underline.cc
+++ b/chrome/browser/ui/views/tabs/tab_group_underline.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/ui/tabs/tab_style.h"
 #include "chrome/browser/ui/views/tabs/tab.h"
 #include "chrome/browser/ui/views/tabs/tab_group_header.h"
+#include "chrome/browser/ui/views/tabs/tab_group_style.h"
 #include "chrome/browser/ui/views/tabs/tab_group_views.h"
 #include "components/tab_groups/tab_group_id.h"
 #include "components/tab_groups/tab_group_visual_data.h"
@@ -18,6 +19,7 @@
 #include "ui/base/metadata/metadata_impl_macros.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/geometry/insets.h"
+#include "ui/gfx/geometry/rect.h"
 #include "ui/views/background.h"
 #include "ui/views/view.h"
 #include "ui/views/view_utils.h"
@@ -25,8 +27,9 @@
 constexpr int TabGroupUnderline::kStrokeThickness;
 
 TabGroupUnderline::TabGroupUnderline(TabGroupViews* tab_group_views,
-                                     const tab_groups::TabGroupId& group)
-    : tab_group_views_(tab_group_views), group_(group) {}
+                                     const tab_groups::TabGroupId& group,
+                                     const TabGroupStyle& style)
+    : tab_group_views_(tab_group_views), group_(group), style_(style) {}
 
 void TabGroupUnderline::OnPaint(gfx::Canvas* canvas) {
   SkPath path = GetPath();
@@ -37,61 +40,83 @@
   canvas->DrawPath(path, flags);
 }
 
-void TabGroupUnderline::UpdateBounds(views::View* leading_view,
-                                     views::View* trailing_view) {
+void TabGroupUnderline::UpdateBounds(const views::View* const leading_view,
+                                     const views::View* const trailing_view) {
   // If there are no views to underline, don't show the underline.
   if (!leading_view) {
     SetVisible(false);
     return;
   }
 
-  gfx::RectF leading_bounds = gfx::RectF(leading_view->bounds());
-  ConvertRectToTarget(leading_view->parent(), parent(), &leading_bounds);
+  const gfx::Rect tab_group_underline_bounds =
+      CalculateTabGroupUnderlineBounds(this, leading_view, trailing_view);
+
+  // The width may be zero if the group underline and header are initialized at
+  // the same time, as with tab restore. In this case, don't show the underline.
+  if (tab_group_underline_bounds.width() == 0) {
+    SetVisible(false);
+    return;
+  }
+
+  SetVisible(
+      !style_->TabGroupUnderlineShouldBeHidden(leading_view, trailing_view));
+  SetBoundsRect(tab_group_underline_bounds);
+}
+
+gfx::Rect TabGroupUnderline::CalculateTabGroupUnderlineBounds(
+    const views::View* const underline_view,
+    const views::View* const leading_view,
+    const views::View* const trailing_view) const {
+  gfx::RectF leading_bounds = views::View::ConvertRectToTarget(
+      leading_view->parent(), underline_view->parent(),
+      gfx::RectF(leading_view->bounds()));
   leading_bounds.Inset(gfx::InsetsF(GetInsetsForUnderline(leading_view)));
 
-  gfx::RectF trailing_bounds = gfx::RectF(trailing_view->bounds());
-  ConvertRectToTarget(trailing_view->parent(), parent(), &trailing_bounds);
+  gfx::RectF trailing_bounds = views::View::ConvertRectToTarget(
+      trailing_view->parent(), underline_view->parent(),
+      gfx::RectF(trailing_view->bounds()));
   trailing_bounds.Inset(gfx::InsetsF(GetInsetsForUnderline(trailing_view)));
 
   gfx::Rect group_bounds = ToEnclosingRect(leading_bounds);
   group_bounds.UnionEvenIfEmpty(ToEnclosingRect(trailing_bounds));
 
-  // The width may be zero if the group underline and header are initialized at
-  // the same time, as with tab restore. In this case, don't show the underline.
-  if (group_bounds.width() == 0) {
-    SetVisible(false);
-    return;
-  }
-
-  SetVisible(true);
   const int y =
       group_bounds.height() - GetLayoutConstant(TABSTRIP_TOOLBAR_OVERLAP);
-  SetBounds(group_bounds.x(), y - kStrokeThickness, group_bounds.width(),
-            kStrokeThickness);
+
+  return gfx::Rect(group_bounds.x(), y - kStrokeThickness, group_bounds.width(),
+                   kStrokeThickness);
 }
 
 gfx::Insets TabGroupUnderline::GetInsetsForUnderline(
-    views::View* sibling_view) const {
+    const views::View* const sibling_view) const {
   // Inset normally from a header - this will always be the left boundary of
   // the group, and may be the right boundary if the group is collapsed.
-  TabGroupHeader* header = views::AsViewClass<TabGroupHeader>(sibling_view);
-  if (header)
-    return gfx::Insets::TLBR(0, GetStrokeInset(), 0, GetStrokeInset());
+  const TabGroupHeader* const header =
+      views::AsViewClass<TabGroupHeader>(sibling_view);
+  if (header) {
+    return gfx::Insets::TLBR(0, TabGroupUnderline::GetStrokeInset(), 0,
+                             TabGroupUnderline::GetStrokeInset());
+  }
 
-  Tab* tab = views::AsViewClass<Tab>(sibling_view);
+  const Tab* const tab = views::AsViewClass<Tab>(sibling_view);
   DCHECK(tab);
 
   // Active tabs need the rounded bits of the underline poking out the sides.
-  if (tab->IsActive())
+  if (tab->IsActive()) {
     return gfx::Insets::TLBR(0, -kStrokeThickness, 0, -kStrokeThickness);
+  }
 
   // Inactive tabs are inset like group headers.
-  int left_inset = GetStrokeInset();
-  int right_inset = GetStrokeInset();
+  const int left_inset = TabGroupUnderline::GetStrokeInset();
+  const int right_inset = TabGroupUnderline::GetStrokeInset();
 
   return gfx::Insets::TLBR(0, left_inset, 0, right_inset);
 }
 
+void TabGroupUnderline::MaybeSetVisible(const bool visible) {
+  SetVisible(visible && !style_->TabGroupUnderlineShouldBeHidden());
+}
+
 // static
 int TabGroupUnderline::GetStrokeInset() {
   return TabStyle::GetTabOverlap() + kStrokeThickness;
diff --git a/chrome/browser/ui/views/tabs/tab_group_underline.h b/chrome/browser/ui/views/tabs/tab_group_underline.h
index c3b575da..4a7be29 100644
--- a/chrome/browser/ui/views/tabs/tab_group_underline.h
+++ b/chrome/browser/ui/views/tabs/tab_group_underline.h
@@ -12,6 +12,7 @@
 #include "ui/views/view.h"
 
 class TabGroupViews;
+class TabGroupStyle;
 
 // View for tab group underlines in the tab strip, which are markers of group
 // members. Underlines are included in the tab
@@ -30,28 +31,39 @@
   static int GetStrokeInset();
 
   TabGroupUnderline(TabGroupViews* tab_group_views,
-                    const tab_groups::TabGroupId& group);
+                    const tab_groups::TabGroupId& group,
+                    const TabGroupStyle& style);
   TabGroupUnderline(const TabGroupUnderline&) = delete;
   TabGroupUnderline& operator=(const TabGroupUnderline&) = delete;
 
   // Updates the bounds of the underline for painting.
-  void UpdateBounds(views::View* leading_view, views::View* trailing_view);
+  void UpdateBounds(const views::View* leading_view,
+                    const views::View* trailing_view);
+  // Checks if the `TabGroupUnderline` should be hidden before
+  // setting the visibility.
+  void MaybeSetVisible(bool visible);
 
   // views::View:
   void OnPaint(gfx::Canvas* canvas) override;
 
  private:
-  // Returns the insets from |sibling_view|'s bounds this underline would have
-  // if it were underlining only |sibling_view|.
-  gfx::Insets GetInsetsForUnderline(views::View* sibling_view) const;
-
+  // Returns the insets from `sibling_view`'s bounds this underline would have
+  // if it were underlining only `sibling_view`.
+  gfx::Insets GetInsetsForUnderline(const views::View* sibling_view) const;
   // The underline is a straight line with half-rounded endcaps. Since this
   // geometry is nontrivial to represent using primitives, it's instead
   // represented using a fill path.
   SkPath GetPath() const;
+  // Returns the tab group underline bounds based on a `leading_view` and a
+  // `trailing_view`.
+  gfx::Rect CalculateTabGroupUnderlineBounds(
+      const views::View* underline_view,
+      const views::View* leading_view,
+      const views::View* trailing_view) const;
 
   const raw_ptr<TabGroupViews> tab_group_views_;
   const tab_groups::TabGroupId group_;
+  const raw_ref<const TabGroupStyle> style_;
 };
 
 #endif  // CHROME_BROWSER_UI_VIEWS_TABS_TAB_GROUP_UNDERLINE_H_
diff --git a/chrome/browser/ui/views/tabs/tab_group_views.cc b/chrome/browser/ui/views/tabs/tab_group_views.cc
index cc91bcb9a..a97b4ba 100644
--- a/chrome/browser/ui/views/tabs/tab_group_views.cc
+++ b/chrome/browser/ui/views/tabs/tab_group_views.cc
@@ -12,6 +12,7 @@
 #include "chrome/browser/ui/views/frame/browser_non_client_frame_view.h"
 #include "chrome/browser/ui/views/tabs/tab_group_header.h"
 #include "chrome/browser/ui/views/tabs/tab_group_highlight.h"
+#include "chrome/browser/ui/views/tabs/tab_group_style.h"
 #include "chrome/browser/ui/views/tabs/tab_group_underline.h"
 #include "chrome/browser/ui/views/tabs/tab_slot_controller.h"
 #include "chrome/browser/ui/views/tabs/tab_strip.h"
@@ -20,6 +21,7 @@
 #include "components/tab_groups/tab_group_color.h"
 #include "components/tab_groups/tab_group_id.h"
 #include "third_party/skia/include/core/SkColor.h"
+#include "ui/base/ui_base_features.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/views/view_utils.h"
@@ -29,14 +31,19 @@
                              TabSlotController& tab_slot_controller,
                              const tab_groups::TabGroupId& group)
     : tab_slot_controller_(tab_slot_controller), group_(group) {
+  style_ = features::IsChromeRefresh2023()
+               ? std::make_unique<const ChromeRefresh2023TabGroupStyle>(*this)
+               : std::make_unique<const TabGroupStyle>(*this);
+  const TabGroupStyle* style = style_.get();
+
   header_ = container_view->AddChildView(
-      std::make_unique<TabGroupHeader>(*tab_slot_controller_, group_));
+      std::make_unique<TabGroupHeader>(*tab_slot_controller_, group_, *style));
   underline_ = container_view->AddChildView(
-      std::make_unique<TabGroupUnderline>(this, group_));
+      std::make_unique<TabGroupUnderline>(this, group_, *style));
   drag_underline_ = drag_container_view->AddChildView(
-      std::make_unique<TabGroupUnderline>(this, group_));
+      std::make_unique<TabGroupUnderline>(this, group_, *style));
   highlight_ = drag_container_view->AddChildView(
-      std::make_unique<TabGroupHighlight>(this, group_));
+      std::make_unique<TabGroupHighlight>(this, group_, *style));
   highlight_->SetVisible(false);
 }
 
@@ -146,7 +153,7 @@
   return !header_ || !header_->GetWidget() || !drag_underline_->GetWidget();
 }
 
-std::tuple<views::View*, views::View*>
+std::tuple<const views::View*, const views::View*>
 TabGroupViews::GetLeadingTrailingGroupViews() const {
   std::vector<views::View*> children = underline_->parent()->children();
   std::vector<views::View*> dragged_children =
diff --git a/chrome/browser/ui/views/tabs/tab_group_views.h b/chrome/browser/ui/views/tabs/tab_group_views.h
index f4c825b..f730c6d 100644
--- a/chrome/browser/ui/views/tabs/tab_group_views.h
+++ b/chrome/browser/ui/views/tabs/tab_group_views.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_UI_VIEWS_TABS_TAB_GROUP_VIEWS_H_
 #define CHROME_BROWSER_UI_VIEWS_TABS_TAB_GROUP_VIEWS_H_
 
+#include <memory>
 #include "base/memory/raw_ptr.h"
 #include "base/memory/raw_ref.h"
 #include "chrome/browser/ui/views/tabs/tab_slot_controller.h"
@@ -17,6 +18,7 @@
 class TabGroupHighlight;
 class TabGroupUnderline;
 class TabStrip;
+class TabGroupStyle;
 
 // The manager of all views associated with a tab group. This handles visual
 // calculations and updates. Painting is done in TabStrip.
@@ -61,6 +63,11 @@
   // tab color. Needed to layer painting for the group background highlight.
   SkColor GetGroupBackgroundColor() const;
 
+  // Finds the first and last tab or group header belonging to `group_` from the
+  // whole Tabstrip.
+  std::tuple<const views::View*, const views::View*>
+  GetLeadingTrailingGroupViews() const;
+
  private:
   const raw_ref<TabSlotController> tab_slot_controller_;
   const tab_groups::TabGroupId group_;
@@ -68,13 +75,10 @@
   raw_ptr<TabGroupHighlight> highlight_;
   raw_ptr<TabGroupUnderline> underline_;
   raw_ptr<TabGroupUnderline> drag_underline_;
+  std::unique_ptr<const TabGroupStyle> style_;
 
   bool InTearDown() const;
 
-  // Finds the first and last tab or group header belonging to |group_| from the
-  // whole TabStrip.
-  std::tuple<views::View*, views::View*> GetLeadingTrailingGroupViews() const;
-
   // Finds the first and last tab or group header belonging to |group_|, only
   // including views that are being dragged.
   std::tuple<views::View*, views::View*> GetLeadingTrailingDraggedGroupViews()
diff --git a/chrome/browser/ui/views/tabs/tab_group_views_unittest.cc b/chrome/browser/ui/views/tabs/tab_group_views_unittest.cc
index 8cb4a92..cddfe72 100644
--- a/chrome/browser/ui/views/tabs/tab_group_views_unittest.cc
+++ b/chrome/browser/ui/views/tabs/tab_group_views_unittest.cc
@@ -5,6 +5,9 @@
 #include "chrome/browser/ui/views/tabs/tab_group_views.h"
 #include <memory>
 
+#include "base/feature_list.h"
+#include "base/test/scoped_feature_list.h"
+#include "chrome/browser/ui/ui_features.h"
 #include "chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.h"
 #include "chrome/browser/ui/views/tabs/fake_tab_slot_controller.h"
 #include "chrome/browser/ui/views/tabs/tab_group_header.h"
@@ -13,9 +16,16 @@
 #include "chrome/test/views/chrome_views_test_base.h"
 #include "ui/views/widget/widget.h"
 
-class TabGroupViewsTest : public ChromeViewsTestBase {
+class TabGroupViewsTest : public ChromeViewsTestBase,
+                          public ::testing::WithParamInterface<bool> {
  public:
-  TabGroupViewsTest() = default;
+  TabGroupViewsTest() {
+    scoped_feature_list_.InitWithFeatures(
+        /*enabled_features=*/GetParam()
+            ? std::vector<base::test::FeatureRef>{features::kChromeRefresh2023}
+            : std::vector<base::test::FeatureRef>{},
+        /*disabled_features=*/{});
+  }
   TabGroupViewsTest(const TabGroupViewsTest&) = delete;
   TabGroupViewsTest& operator=(const TabGroupViewsTest&) = delete;
   ~TabGroupViewsTest() override = default;
@@ -55,9 +65,10 @@
   std::unique_ptr<FakeTabSlotController> tab_slot_controller_;
   tab_groups::TabGroupId id_ = tab_groups::TabGroupId::GenerateNew();
   std::unique_ptr<TabGroupViews> group_views_;
+  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
-TEST_F(TabGroupViewsTest, GroupViewsCreated) {
+TEST_P(TabGroupViewsTest, GroupViewsCreated) {
   EXPECT_NE(nullptr, group_views_->header());
   EXPECT_NE(nullptr, group_views_->underline());
   EXPECT_NE(nullptr, group_views_->drag_underline());
@@ -70,7 +81,7 @@
 }
 
 // Underline should actually underline the group.
-TEST_F(TabGroupViewsTest, UnderlineBoundsNoDrag) {
+TEST_P(TabGroupViewsTest, UnderlineBoundsNoDrag) {
   TabGroupHeader* header = group_views_->header();
   Tab* tab_1 = tab_container_->AddChildView(
       std::make_unique<Tab>(tab_slot_controller_.get()));
@@ -99,9 +110,44 @@
   EXPECT_FALSE(group_views_->drag_underline()->GetVisible());
 }
 
+// Underline should not be visible with chrome refresh flag when only header is
+// visible.
+TEST_P(TabGroupViewsTest, UnderlineBoundsWhenTabsAreNotVisible) {
+  TabGroupHeader* header = group_views_->header();
+  Tab* tab_1 = tab_container_->AddChildView(
+      std::make_unique<Tab>(tab_slot_controller_.get()));
+  tab_1->set_group(id_);
+  Tab* tab_2 = tab_container_->AddChildView(
+      std::make_unique<Tab>(tab_slot_controller_.get()));
+  tab_2->set_group(id_);
+
+  header->SetBounds(0, 0, 100, 0);
+  tab_1->SetBounds(50, 0, 100, 0);
+  tab_2->SetBounds(100, 0, 100, 0);
+
+  tab_1->SetVisible(false);
+  tab_2->SetVisible(false);
+  group_views_->UpdateBounds();
+
+  // The condition is true when the ChromeRefreshFlag is turned on. The
+  // underline should not be visible when collapsed in this case.
+  if (!GetParam()) {
+    EXPECT_TRUE(group_views_->underline()->GetVisible());
+    const gfx::Rect underline_bounds = group_views_->underline()->bounds();
+    // Underline should begin from the header.
+    EXPECT_GT(underline_bounds.x(), header->bounds().x());
+    // Underline should end within the last tab.
+    EXPECT_LT(underline_bounds.right(), tab_2->bounds().right());
+    EXPECT_FALSE(group_views_->drag_underline()->GetVisible());
+  } else {
+    EXPECT_FALSE(group_views_->underline()->GetVisible());
+    EXPECT_GT(group_views_->underline()->width(), 0);
+  }
+}
+
 // Drag_underline should underline the group when the group is being dragged,
 // and the highlight should highlight it.
-TEST_F(TabGroupViewsTest, UnderlineBoundsHeaderDrag) {
+TEST_P(TabGroupViewsTest, UnderlineBoundsHeaderDrag) {
   TabGroupHeader* header = group_views_->header();
   drag_context_->AddChildView(header);
   Tab* tab_1 = drag_context_->AddChildView(
@@ -143,7 +189,7 @@
 
 // Underline and drag_underline should align with one another correctly when
 // dragging a tab within a group.
-TEST_F(TabGroupViewsTest, UnderlineBoundsDragTabInGroup) {
+TEST_P(TabGroupViewsTest, UnderlineBoundsDragTabInGroup) {
   TabGroupHeader* header = group_views_->header();
   Tab* other_tab = tab_container_->AddChildView(
       std::make_unique<Tab>(tab_slot_controller_.get()));
@@ -268,3 +314,5 @@
     EXPECT_EQ(drag_underline_bounds.right(), dragged_tab->bounds().right());
   }
 }
+
+INSTANTIATE_TEST_SUITE_P(All, TabGroupViewsTest, ::testing::Bool());
diff --git a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_view.cc b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_view.cc
index 5aaae78..06122c49 100644
--- a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_view.cc
+++ b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_view.cc
@@ -27,8 +27,7 @@
 #include "ui/views/view_utils.h"
 #include "ui/views/window/hit_test_utils.h"
 
-WebAppFrameToolbarView::WebAppFrameToolbarView(views::Widget* widget,
-                                               BrowserView* browser_view)
+WebAppFrameToolbarView::WebAppFrameToolbarView(BrowserView* browser_view)
     : browser_view_(browser_view) {
   DCHECK(browser_view_);
   DCHECK(web_app::AppBrowserController::IsWebApp(browser_view_->browser()));
@@ -67,9 +66,8 @@
                                views::MaximumFlexSizeRule::kUnbounded)
           .WithOrder(3));
 
-  right_container_ =
-      AddChildView(std::make_unique<WebAppToolbarButtonContainer>(
-          widget, browser_view, this));
+  right_container_ = AddChildView(
+      std::make_unique<WebAppToolbarButtonContainer>(browser_view, this));
   right_container_->SetProperty(
       views::kFlexBehaviorKey,
       views::FlexSpecification(right_container_->GetFlexRule()).WithOrder(1));
diff --git a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_view.h b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_view.h
index 6ff04f3c..2ad80a0 100644
--- a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_view.h
+++ b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_view.h
@@ -20,7 +20,6 @@
 namespace views {
 class View;
 class ViewTargeterDelegate;
-class Widget;
 }  // namespace views
 
 class BrowserView;
@@ -35,7 +34,7 @@
                                public views::ViewTargeterDelegate {
  public:
   METADATA_HEADER(WebAppFrameToolbarView);
-  WebAppFrameToolbarView(views::Widget* widget, BrowserView* browser_view);
+  explicit WebAppFrameToolbarView(BrowserView* browser_view);
   WebAppFrameToolbarView(const WebAppFrameToolbarView&) = delete;
   WebAppFrameToolbarView& operator=(const WebAppFrameToolbarView&) = delete;
   ~WebAppFrameToolbarView() override;
diff --git a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_toolbar_button_container.cc b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_toolbar_button_container.cc
index 02868707..3138e43 100644
--- a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_toolbar_button_container.cc
+++ b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_toolbar_button_container.cc
@@ -55,7 +55,6 @@
 }
 
 WebAppToolbarButtonContainer::WebAppToolbarButtonContainer(
-    views::Widget* widget,
     BrowserView* browser_view,
     ToolbarButtonProvider* toolbar_button_provider)
     : browser_view_(browser_view),
@@ -177,7 +176,6 @@
   }
 
   browser_view_->immersive_mode_controller()->AddObserver(this);
-  scoped_widget_observation_.Observe(widget);
 }
 
 WebAppToolbarButtonContainer::~WebAppToolbarButtonContainer() {
diff --git a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_toolbar_button_container.h b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_toolbar_button_container.h
index 5ee7bcfd..4668ba5 100644
--- a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_toolbar_button_container.h
+++ b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_toolbar_button_container.h
@@ -19,8 +19,6 @@
 #include "ui/base/metadata/metadata_header_macros.h"
 #include "ui/views/layout/flex_layout_types.h"
 #include "ui/views/view.h"
-#include "ui/views/widget/widget.h"
-#include "ui/views/widget/widget_observer.h"
 
 class WebAppContentSettingsContainer;
 class BrowserView;
@@ -36,8 +34,7 @@
                                      public ContentSettingImageView::Delegate,
                                      public ImmersiveModeController::Observer,
                                      public PageActionIconView::Delegate,
-                                     public PageActionIconContainer,
-                                     public views::WidgetObserver {
+                                     public PageActionIconContainer {
  public:
   METADATA_HEADER(WebAppToolbarButtonContainer);
 
@@ -54,8 +51,7 @@
   // The total duration of the origin fade animation.
   static base::TimeDelta OriginTotalDuration();
 
-  WebAppToolbarButtonContainer(views::Widget* widget,
-                               BrowserView* browser_view,
+  WebAppToolbarButtonContainer(BrowserView* browser_view,
                                ToolbarButtonProvider* toolbar_button_provider);
   ~WebAppToolbarButtonContainer() override;
 
@@ -136,9 +132,6 @@
   // views::View:
   void AddedToWidget() override;
 
-  base::ScopedObservation<views::Widget, views::WidgetObserver>
-      scoped_widget_observation_{this};
-
   // Timers for synchronising their respective parts of the titlebar animation.
   base::OneShotTimer animation_start_delay_;
   base::OneShotTimer icon_fade_in_delay_;
diff --git a/chrome/browser/ui/webui/management/management_ui.cc b/chrome/browser/ui/webui/management/management_ui.cc
index 572d77f..4414485 100644
--- a/chrome/browser/ui/webui/management/management_ui.cc
+++ b/chrome/browser/ui/webui/management/management_ui.cc
@@ -53,7 +53,7 @@
                     ManagementUI::GetManagementPageSubtitle(profile));
 
   static constexpr webui::LocalizedString kLocalizedStrings[] = {
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS)
     {"learnMore", IDS_LEARN_MORE},
     {"localTrustRoots", IDS_MANAGEMENT_LOCAL_TRUST_ROOTS},
     {"managementTrustRootsConfigured", IDS_MANAGEMENT_TRUST_ROOTS_CONFIGURED},
@@ -91,9 +91,11 @@
     {kManagementOnFileTransferEvent, IDS_MANAGEMENT_FILE_TRANSFER_EVENT},
     {kManagementOnFileTransferVisibleData,
      IDS_MANAGEMENT_FILE_TRANSFER_VISIBLE_DATA},
+#endif  // BUILDFLAG(IS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
     {kManagementScreenCaptureEvent, IDS_MANAGEMENT_SCREEN_CAPTURE_EVENT},
     {kManagementScreenCaptureData, IDS_MANAGEMENT_SCREEN_CAPTURE_DATA},
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#endif  // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
     {"browserReporting", IDS_MANAGEMENT_BROWSER_REPORTING},
     {"browserReportingExplanation",
      IDS_MANAGEMENT_BROWSER_REPORTING_EXPLANATION},
diff --git a/chrome/browser/ui/webui/management/management_ui_handler.cc b/chrome/browser/ui/webui/management/management_ui_handler.cc
index 33a6965..e4e33da 100644
--- a/chrome/browser/ui/webui/management/management_ui_handler.cc
+++ b/chrome/browser/ui/webui/management/management_ui_handler.cc
@@ -171,7 +171,12 @@
   kUserActivity
 };
 
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
+const char kManagementScreenCaptureEvent[] = "managementScreenCaptureEvent";
+const char kManagementScreenCaptureData[] = "managementScreenCaptureData";
+#endif  // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
+
+#if BUILDFLAG(IS_CHROMEOS)
 const char kManagementLogUploadEnabled[] = "managementLogUploadEnabled";
 const char kManagementReportActivityTimes[] = "managementReportActivityTimes";
 const char kManagementReportDeviceAudioStatus[] =
@@ -194,8 +199,6 @@
 const char kManagementReportCRDSessions[] = "managementReportCRDSessions";
 const char kManagementReportDlpEvents[] = "managementReportDlpEvents";
 const char kManagementOnFileTransferEvent[] = "managementOnFileTransferEvent";
-const char kManagementScreenCaptureEvent[] = "managementScreenCaptureEvent";
-const char kManagementScreenCaptureData[] = "managementScreenCaptureData";
 const char kManagementOnFileTransferVisibleData[] =
     "managementOnFileTransferVisibleData";
 const char kManagementPrinting[] = "managementPrinting";
@@ -205,7 +208,7 @@
 const char kAccountManagedInfo[] = "accountManagedInfo";
 const char kDeviceManagedInfo[] = "deviceManagedInfo";
 const char kOverview[] = "overview";
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 const char kCustomerLogo[] = "customerLogo";
 
@@ -316,8 +319,9 @@
                             const policy::StatusCollector* collector,
                             const policy::SystemLogUploader* uploader,
                             Profile* profile) {
-  if (!collector || !profile || !uploader)
+  if (!collector || !profile || !uploader) {
     return;
+  }
 
   // Elements appear on the page in the order they are added.
   bool report_device_peripherals = false;
@@ -454,8 +458,9 @@
     scoped_refptr<const extensions::Extension> extension) {
   base::Value::List permission_messages;
   // Only consider force installed extensions
-  if (!extensions::Manifest::IsPolicyLocation(extension->location()))
+  if (!extensions::Manifest::IsPolicyLocation(extension->location())) {
     return permission_messages;
+  }
 
   extensions::PermissionIDSet permissions =
       extensions::PermissionMessageProvider::Get()
@@ -467,8 +472,9 @@
       extensions::PermissionMessageProvider::Get()->GetPermissionMessages(
           permissions);
 
-  for (const auto& message : messages)
+  for (const auto& message : messages) {
     permission_messages.Append(message.message());
+  }
 
   return permission_messages;
 }
@@ -721,8 +727,9 @@
 const policy::DeviceCloudPolicyManagerAsh*
 ManagementUIHandler::GetDeviceCloudPolicyManager() const {
   // Only check for report status in managed environment.
-  if (!device_managed_)
+  if (!device_managed_) {
     return nullptr;
+  }
 
   const policy::BrowserPolicyConnectorAsh* connector =
       g_browser_process->platform_part()->browser_policy_connector_ash();
@@ -809,8 +816,9 @@
   if (manager) {
     uploader = manager->GetStatusUploader();
     syslog_uploader = manager->GetSystemLogUploader();
-    if (uploader)
+    if (uploader) {
       collector = uploader->status_collector();
+    }
   }
   AddDeviceReportingInfo(&report_sources, collector, syslog_uploader, profile);
   return report_sources;
@@ -839,8 +847,9 @@
   base::Value::Dict response;
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   std::string enterprise_manager = GetDeviceManager();
-  if (enterprise_manager.empty())
+  if (enterprise_manager.empty()) {
     enterprise_manager = GetAccountManager(profile);
+  }
   AddUpdateRequiredEolInfo(&response);
   AddMonitoredNetworkPrivacyDisclosure(&response);
 #else
@@ -911,8 +920,9 @@
   response.Set("managed", managed_());
   GetManagementStatus(profile, &response);
   AsyncUpdateLogo();
-  if (!fetched_image_.empty())
+  if (!fetched_image_.empty()) {
     response.Set(kCustomerLogo, base::Value(fetched_image_));
+  }
   return response;
 }
 
@@ -963,13 +973,13 @@
                                   kManagementOnPageVisitedVisibleData, &info);
   }
 
-#if BUILDFLAG(IS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
   if (capture_policy::IsGetDisplayMediaSetSelectAllScreensAllowedForAnySite(
           profile)) {
     AddThreatProtectionPermission(kManagementScreenCaptureEvent,
                                   kManagementScreenCaptureData, &info);
   }
-#endif  // BUILDFLAG(IS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
 
   const std::string enterprise_manager =
       connectors_service->GetManagementDomain();
@@ -992,11 +1002,13 @@
   auto* managed_configuration =
       ManagedConfigurationAPIFactory::GetForProfile(profile);
 
-  if (!managed_configuration)
+  if (!managed_configuration) {
     return managed_websites;
+  }
 
-  for (const auto& entry : managed_configuration->GetManagedOrigins())
+  for (const auto& entry : managed_configuration->GetManagedOrigins()) {
     managed_websites.Append(entry.Serialize());
+  }
 
   return managed_websites;
 }
@@ -1027,8 +1039,9 @@
 
 void ManagementUIHandler::OnFetchComplete(const GURL& url,
                                           const SkBitmap* bitmap) {
-  if (!bitmap)
+  if (!bitmap) {
     return;
+  }
   fetched_image_ = webui::GetBitmapDataUrl(*bitmap);
   logo_url_ = url;
   // Fire listener to reload managed data.
@@ -1071,10 +1084,12 @@
   std::string device_domain;
   policy::BrowserPolicyConnectorAsh* connector =
       g_browser_process->platform_part()->browser_policy_connector_ash();
-  if (device_managed_)
+  if (device_managed_) {
     device_domain = connector->GetEnterpriseDomainManager();
-  if (device_domain.empty() && connector->IsActiveDirectoryManaged())
+  }
+  if (device_domain.empty() && connector->IsActiveDirectoryManaged()) {
     device_domain = connector->GetRealm();
+  }
   return device_domain;
 }
 
@@ -1100,8 +1115,9 @@
   const bool primary_user_managed =
       primary_profile ? IsProfileManaged(primary_profile) : false;
 
-  if (primary_user_managed)
+  if (primary_user_managed) {
     account_manager = GetAccountManager(primary_profile);
+  }
 
   std::string device_manager = GetDeviceManager();
 
@@ -1148,8 +1164,9 @@
   policy::PolicyCertService* policy_service =
       policy::PolicyCertServiceFactory::GetForProfile(
           Profile::FromWebUI(web_ui()));
-  if (policy_service && policy_service->has_policy_certificates())
+  if (policy_service && policy_service->has_policy_certificates()) {
     trust_roots_configured = base::Value(true);
+  }
 
   ResolveJavascriptCallback(args[0] /* callback_id */, trust_roots_configured);
 }
@@ -1268,8 +1285,9 @@
   account_managed_ = IsProfileManaged(profile) || IsBrowserManaged();
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
 
-  if (managed_state_changed)
+  if (managed_state_changed) {
     FireWebUIListener("managed_data_changed");
+  }
 }
 
 void ManagementUIHandler::OnPolicyUpdated(
@@ -1282,8 +1300,9 @@
 }
 
 void ManagementUIHandler::AddObservers() {
-  if (has_observers_)
+  if (has_observers_) {
     return;
+  }
 
   has_observers_ = true;
 
@@ -1311,8 +1330,9 @@
 }
 
 void ManagementUIHandler::RemoveObservers() {
-  if (!has_observers_)
+  if (!has_observers_) {
     return;
+  }
 
   has_observers_ = false;
 
diff --git a/chrome/browser/ui/webui/management/management_ui_handler.h b/chrome/browser/ui/webui/management/management_ui_handler.h
index ca1797da..26d34ed 100644
--- a/chrome/browser/ui/webui/management/management_ui_handler.h
+++ b/chrome/browser/ui/webui/management/management_ui_handler.h
@@ -24,9 +24,14 @@
 #include "extensions/common/extension_id.h"
 #include "url/gurl.h"
 
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
 // Constants defining the IDs for the localized strings sent to the page as
 // load time data.
+extern const char kManagementScreenCaptureEvent[];
+extern const char kManagementScreenCaptureData[];
+#endif  // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
+
+#if BUILDFLAG(IS_CHROMEOS)
 extern const char kManagementLogUploadEnabled[];
 extern const char kManagementReportActivityTimes[];
 extern const char kManagementReportDeviceAudioStatus[];
@@ -48,9 +53,7 @@
 extern const char kManagementReportAndroidApplications[];
 extern const char kManagementOnFileTransferEvent[];
 extern const char kManagementOnFileTransferVisibleData[];
-extern const char kManagementScreenCaptureEvent[];
-extern const char kManagementScreenCaptureData[];
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 extern const char kOnPremReportingExtensionStableId[];
 extern const char kOnPremReportingExtensionBetaId[];
diff --git a/chrome/browser/ui/webui/settings/ash/BUILD.gn b/chrome/browser/ui/webui/settings/ash/BUILD.gn
index 5053c5ec..ffc2ee35 100644
--- a/chrome/browser/ui/webui/settings/ash/BUILD.gn
+++ b/chrome/browser/ui/webui/settings/ash/BUILD.gn
@@ -12,7 +12,6 @@
     "//chrome/browser/ui/webui/settings/ash/search:mojo_bindings_js",
     "//chrome/browser/ui/webui/settings/chromeos/constants:mojom_js",
     "//chromeos/ash/components/audio/public/mojom/:mojom_js",
-    "//ui/webui/resources/cr_components/app_management:mojo_bindings_js",
   ]
 }
 
diff --git a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome.mojom b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome.mojom
index c2e80f0e..aee65c38 100644
--- a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome.mojom
+++ b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome.mojom
@@ -47,6 +47,8 @@
   skia.mojom.SkColor color_picker_icon_color;
   // True if the colors are managed by a policy.
   bool colors_managed_by_policy;
+  // Selected collection for daily refresh.
+  string? daily_refresh_collection_id;
 };
 
 struct ChromeColor {
@@ -141,6 +143,10 @@
       url.mojom.Url attribution_url, url.mojom.Url image_url,
       url.mojom.Url thumbnail_url);
 
+  // Sets collection id for daily refresh. When |collection_id| is empty, the
+  // daily refresh is turned off.
+  SetDailyRefreshCollectionId(string collection_id);
+
   // Open Chrome Web Store's theme page in a new tab.
   OpenChromeWebStore();
 
diff --git a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler.cc b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler.cc
index 8c53c80..b6a18cc 100644
--- a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler.cc
+++ b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler.cc
@@ -220,6 +220,9 @@
   }
   theme->color_picker_icon_color =
       web_contents_->GetColorProvider().GetColor(kColorNewTabPageText);
+  if (custom_background.has_value()) {
+    theme->daily_refresh_collection_id = custom_background->collection_id;
+  }
   auto* native_theme = ui::NativeTheme::GetInstanceForNativeUi();
   CHECK(native_theme);
   theme->system_dark_mode = native_theme->ShouldUseDarkColors();
@@ -282,6 +285,16 @@
       /* collection_id= */ "");
 }
 
+void CustomizeChromePageHandler::SetDailyRefreshCollectionId(
+    const std::string& collection_id) {
+  // Populating the |collection_id| turns on refresh daily which overrides the
+  // the selected image.
+  ntp_custom_background_service_->SetCustomBackgroundInfo(
+      /* image_url */ GURL(), /* thumbnail_url */ GURL(),
+      /* attribution_line_1= */ "", /* attribution_line_2= */ "",
+      /* action_url= */ GURL(), collection_id);
+}
+
 void CustomizeChromePageHandler::OpenChromeWebStore() {
   NavigateParams navigate_params(
       profile_, GURL("https://chrome.google.com/webstore?category=theme"),
diff --git a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler.h b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler.h
index 8ef0d30..3824256 100644
--- a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler.h
+++ b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler.h
@@ -69,6 +69,7 @@
                           const GURL& attribution_url,
                           const GURL& image_url,
                           const GURL& thumbnail_url) override;
+  void SetDailyRefreshCollectionId(const std::string& collection_id) override;
   void OpenChromeWebStore() override;
   void OpenThirdPartyThemePage(const std::string& theme_id) override;
   void SetModulesVisible(bool visible) override;
diff --git a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler_unittest.cc b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler_unittest.cc
index be3ecebe..3ae9c47 100644
--- a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler_unittest.cc
+++ b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler_unittest.cc
@@ -403,6 +403,7 @@
   custom_background.custom_background_attribution_line_1 = "foo line";
   custom_background.is_uploaded_image = false;
   custom_background.custom_background_main_color = SK_ColorGREEN;
+  custom_background.collection_id = "test_collection";
   ON_CALL(mock_ntp_custom_background_service_, GetCustomBackground())
       .WillByDefault(testing::Return(absl::make_optional(custom_background)));
   ON_CALL(mock_theme_service(), GetAutogeneratedThemeColor())
@@ -435,6 +436,7 @@
   EXPECT_EQ(web_contents().GetColorProvider().GetColor(kColorNewTabPageText),
             theme->color_picker_icon_color);
   EXPECT_TRUE(theme->colors_managed_by_policy);
+  EXPECT_EQ("test_collection", theme->daily_refresh_collection_id);
 }
 
 TEST_P(CustomizeChromePageHandlerSetThemeTest, SetUploadedImage) {
@@ -662,6 +664,12 @@
             browser().tab_strip_model()->GetWebContentsAt(0)->GetURL());
 }
 
+TEST_F(CustomizeChromePageHandlerTest, SetDailyRefreshCollectionId) {
+  EXPECT_CALL(mock_ntp_custom_background_service_, SetCustomBackgroundInfo)
+      .Times(1);
+  handler().SetDailyRefreshCollectionId("test_id");
+}
+
 class CustomizeChromePageHandlerWithModulesTest
     : public CustomizeChromePageHandlerTest {
  public:
diff --git a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_ui.cc b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_ui.cc
index c0a2465..491eb14b 100644
--- a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_ui.cc
+++ b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_ui.cc
@@ -56,6 +56,7 @@
       {"uploadedImage", IDS_NTP_CUSTOMIZE_UPLOADED_IMAGE_LABEL},
       {"resetToClassicChrome",
        IDS_NTP_CUSTOMIZE_CHROME_RESET_TO_CLASSIC_CHROME_LABEL},
+      {"refreshDaily", IDS_NTP_CUSTOM_BG_DAILY_REFRESH},
       // Shortcut strings.
       {"mostVisited", IDS_NTP_CUSTOMIZE_MOST_VISITED_LABEL},
       {"myShortcuts", IDS_NTP_CUSTOMIZE_MY_SHORTCUTS_LABEL},
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index ba2b5524..e462611 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1673611163-3128b65fa391456b4abcfd06837aa499c35149e7.profdata
+chrome-mac-arm-main-1673632771-2b75619b4f8333d9bd191662efd87dc893655a02.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index c3f6d26e..ad07eb4c 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1673611163-c55e9c4b4fd75de6090ec1b45d9b4716f5c9fd3c.profdata
+chrome-win32-main-1673621965-a306175d10f04a7a84323a9b181698eec49fe756.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 5fb1f26..c82330a5 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1673611163-634681d8854f60c9f57d7472672f4c708c7ea337.profdata
+chrome-win64-main-1673621965-d40a509be491361eace657324fa40d4a7bdfa5da.profdata
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 8d21d1c..e515228 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -252,12 +252,7 @@
 // offline if no custom page is provided by developer.
 BASE_FEATURE(kPWAsDefaultOfflinePage,
              "PWAsDefaultOfflinePage",
-#if BUILDFLAG(IS_ANDROID)
-             base::FEATURE_ENABLED_BY_DEFAULT
-#else
-             base::FEATURE_DISABLED_BY_DEFAULT
-#endif
-);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 // API that allows PWAs manually minimizing, maximizing and restoring windows.
 BASE_FEATURE(kDesktopPWAsAdditionalWindowingControls,
diff --git a/chrome/common/extensions/api/autotest_private.idl b/chrome/common/extensions/api/autotest_private.idl
index b4111e0..3af2082 100644
--- a/chrome/common/extensions/api/autotest_private.idl
+++ b/chrome/common/extensions/api/autotest_private.idl
@@ -703,6 +703,12 @@
   // Collected ui::ThroughputTracker data for one animation. It is based on
   // cc::FrameSequenceMetrics::ThroughputData.
   dictionary ThroughputTrackerAnimationData {
+    // Animation start time in milliseconds, relative to when
+    // `startThroughputTrackerDataCollection` is called.
+    long startOffsetMs;
+    // Animation stop time in milliseconds, relative to when
+    // `startThroughputTrackerDataCollection` is called.
+    long stopOffsetMs;
     // Number of frames expected to be shown for this animation.
     long framesExpected;
     // Number of frames actually shown for this animation.
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc
index ee1ac93..ad77a53c 100644
--- a/chrome/common/webui_url_constants.cc
+++ b/chrome/common/webui_url_constants.cc
@@ -620,6 +620,7 @@
 const char kPrivacySandboxSubPage[] = "privacySandbox";
 
 #if !BUILDFLAG(IS_ANDROID)
+const char kAdPrivacySubPagePath[] = "/adPrivacy";
 const char kPrivacySandboxSubPagePath[] = "/privacySandbox";
 #endif
 
diff --git a/chrome/common/webui_url_constants.h b/chrome/common/webui_url_constants.h
index e7c375d3..6e372cd 100644
--- a/chrome/common/webui_url_constants.h
+++ b/chrome/common/webui_url_constants.h
@@ -544,6 +544,7 @@
 extern const char kPrivacySandboxSubPage[];
 
 #if !BUILDFLAG(IS_ANDROID)
+extern const char kAdPrivacySubPagePath[];
 extern const char kPrivacySandboxSubPagePath[];
 #endif
 
diff --git a/chrome/install_static/BUILD.gn b/chrome/install_static/BUILD.gn
index 1de210a..b3ab7737 100644
--- a/chrome/install_static/BUILD.gn
+++ b/chrome/install_static/BUILD.gn
@@ -59,7 +59,7 @@
         "google_chrome_install_modes.cc",
         "google_chrome_install_modes.h",
       ]
-    } else if (is_chrome_for_testing_branded) {
+    } else if (use_internal_chrome_for_testing_icons) {
       sources += [
         "google_chrome_for_testing_install_modes.cc",
         "google_chrome_for_testing_install_modes.h",
diff --git a/chrome/install_static/install_modes.h b/chrome/install_static/install_modes.h
index d4c95bee..7f55956 100644
--- a/chrome/install_static/install_modes.h
+++ b/chrome/install_static/install_modes.h
@@ -41,7 +41,7 @@
 //   kInstallModes.
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
 #include "chrome/install_static/google_chrome_install_modes.h"
-#elif BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#elif BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
 #include "chrome/install_static/google_chrome_for_testing_install_modes.h"
 #else
 #include "chrome/install_static/chromium_install_modes.h"
diff --git a/chrome/install_static/install_util_unittest.cc b/chrome/install_static/install_util_unittest.cc
index 0636652..881260c 100644
--- a/chrome/install_static/install_util_unittest.cc
+++ b/chrome/install_static/install_util_unittest.cc
@@ -309,7 +309,7 @@
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
     static constexpr wchar_t kPolicyKey[] =
         L"Software\\Policies\\Google\\Chrome";
-#elif BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#elif BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
     static constexpr wchar_t kPolicyKey[] =
         L"Software\\Policies\\Google\\Chrome for Testing";
 #else
@@ -358,7 +358,7 @@
       L"Google\\Chrome Dev",
       L"Google\\Chrome SxS",
   };
-#elif BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#elif BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
   // The directory strings for the brand's install modes; parallel to
   // kInstallModes.
   static constexpr const wchar_t* kInstallDirs[] = {
@@ -387,7 +387,7 @@
       L"Software\\Google\\Chrome Dev",
       L"Software\\Google\\Chrome SxS",
   };
-#elif BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#elif BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
   // The registry path strings for the brand's install modes; parallel to
   // kInstallModes.
   static constexpr const wchar_t* kRegistryPaths[] = {
@@ -419,7 +419,7 @@
       L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"  // (cont'd)
       L"Google Chrome SxS",
   };
-#elif BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#elif BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
   // The registry path strings for the brand's install modes; parallel to
   // kInstallModes.
   static constexpr const wchar_t* kUninstallRegistryPaths[] = {
@@ -469,7 +469,7 @@
       L"ChromeDev",
       L"ChromeCanary",
   };
-#elif BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#elif BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
   // The base app ids for the brand's install modes; parallel to kInstallModes.
   static constexpr const wchar_t* kBaseAppIds[] = {
       L"ChromeForTesting",
@@ -517,7 +517,7 @@
       L"{F01C03EB-D431-4C83-8D7A-902771E732FA}",  // Google Chrome Dev.
       L"{FA372A6E-149F-4E95-832D-8F698D40AD7F}",  // Google Chrome SxS (Canary).
   };
-#elif BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#elif BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
   // The toast activator CLSIDs for the brand's install modes; parallel to
   // kInstallModes.
   static constexpr CLSID kToastActivatorClsids[] = {
@@ -588,7 +588,7 @@
       L"{DA7FDCA5-2CAA-4637-AA17-0740584DE7DA}",  // Google Chrome Dev.
       L"{704C2872-2049-435E-A469-0A534313C42B}",  // Google Chrome SxS (Canary).
   };
-#elif BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#elif BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
   // The Elevator CLSIDs, one for each of the kInstallModes.
   static constexpr CLSID kElevatorClsids[] = {
       {0x724349BF,
@@ -666,7 +666,7 @@
       L"{BB2AA26B-343A-4072-8B6F-80557B8CE571}",  // Google Chrome Dev.
       L"{4F7CE041-28E9-484F-9DD0-61A8CACEFEE4}",  // Google Chrome Canary.
   };
-#elif BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#elif BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
   // The Elevator IIDs, one for each of the kInstallModes.
   static constexpr IID kElevatorIids[] = {
       {0x3DC48E97,
@@ -784,7 +784,7 @@
       L"S-1-15-2-3251537155-1984446955-2931258699-841473695-1938553385-"
       L"924012150-",  // Google Chrome SxS (Canary).
   };
-#elif BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#elif BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
   static constexpr const wchar_t* kSandBoxSids[] = {
       L"S-1-15-2-3251537155-1984446955-2931258699-841473695-1938553385-"
       L"924012153-",  // Google Chrome for Testing
@@ -819,7 +819,7 @@
                          InstallStaticUtilTest,
                          testing::Combine(testing::Values(CANARY_INDEX),
                                           testing::Values("user")));
-#elif BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#elif BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
 // Chrome for Testing is only at user level.
 INSTANTIATE_TEST_SUITE_P(
     ChromeForTesting,
diff --git a/chrome/install_static/product_install_details_unittest.cc b/chrome/install_static/product_install_details_unittest.cc
index 5e46301..02692e0 100644
--- a/chrome/install_static/product_install_details_unittest.cc
+++ b/chrome/install_static/product_install_details_unittest.cc
@@ -186,7 +186,7 @@
         L"canary",
     },
 };
-#elif BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#elif BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
 constexpr TestData kTestData[] = {
     {
         L"C:\\Users\\user\\AppData\\Local\\Google\\Chrome for "
diff --git a/chrome/install_static/user_data_dir_win_unittest.cc b/chrome/install_static/user_data_dir_win_unittest.cc
index 262d938..6924dec 100644
--- a/chrome/install_static/user_data_dir_win_unittest.cc
+++ b/chrome/install_static/user_data_dir_win_unittest.cc
@@ -24,9 +24,9 @@
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
 const wchar_t kPolicyRegistryKey[] = L"SOFTWARE\\Policies\\Google\\Chrome";
 const wchar_t kUserDataDirNameSuffix[] = L"\\Google\\Chrome\\User Data";
-#elif BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
-const wchar_t kPolicyRegistryKey[] =
-    L"SOFTWARE\\Policies\\Google\\Chrome for Testing";
+#elif BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
+// kPolicyRegistryKey: same as Google Chrome
+const wchar_t kPolicyRegistryKey[] = L"SOFTWARE\\Policies\\Google\\Chrome";
 const wchar_t kUserDataDirNameSuffix[] =
     L"\\Google\\Chrome for Testing\\User Data";
 #else
diff --git a/chrome/installer/mini_installer/mini_installer_constants.cc b/chrome/installer/mini_installer/mini_installer_constants.cc
index 1d4aa84..0b59bf4 100644
--- a/chrome/installer/mini_installer/mini_installer_constants.cc
+++ b/chrome/installer/mini_installer/mini_installer_constants.cc
@@ -68,7 +68,7 @@
     L"Software\\Google\\Update\\ClientState\\";
 // The path to the key in which kCleanupRegistryValue is found.
 const wchar_t kCleanupRegistryKey[] = L"Software\\Google";
-#elif BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#elif BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
 // The path to the key containing each app's Clients registry key.
 // No trailing slash on this one because the app's GUID is not appended.
 const wchar_t kClientsKeyBase[] = L"Software\\Chrome for Testing";
diff --git a/chrome/installer/setup/install_unittest.cc b/chrome/installer/setup/install_unittest.cc
index 7e945f3..cc2042f 100644
--- a/chrome/installer/setup/install_unittest.cc
+++ b/chrome/installer/setup/install_unittest.cc
@@ -198,7 +198,7 @@
     CreateVisualElementsManifestTest,
     testing::Combine(testing::Values(install_static::CANARY_INDEX),
                      testing::Values(kExpectedCanaryManifest)));
-#elif BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#elif BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
 INSTANTIATE_TEST_SUITE_P(
     ChromeForTesting,
     CreateVisualElementsManifestTest,
diff --git a/chrome/installer/setup/install_worker_unittest.cc b/chrome/installer/setup/install_worker_unittest.cc
index e33e315..a77a008 100644
--- a/chrome/installer/setup/install_worker_unittest.cc
+++ b/chrome/installer/setup/install_worker_unittest.cc
@@ -273,7 +273,7 @@
 //------------------------------------------------------------------------------
 
 // Chrome for Testing does not support system-level installations.
-#if !BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#if !BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
 TEST_F(InstallWorkerTest, TestInstallChromeSystem) {
   const bool system_level = true;
   NiceMock<MockWorkItemList> work_item_list;
diff --git a/chrome/installer/setup/setup_install_details_unittest.cc b/chrome/installer/setup/setup_install_details_unittest.cc
index 76a69f0..7a4f047a 100644
--- a/chrome/installer/setup/setup_install_details_unittest.cc
+++ b/chrome/installer/setup/setup_install_details_unittest.cc
@@ -432,7 +432,7 @@
         L"extended",                   // Expect the channel override.
     },
 };
-#elif BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#elif BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
 constexpr TestData kTestData[] = {
     // User-level test cases.
     {
diff --git a/chrome/installer/setup/setup_util.cc b/chrome/installer/setup/setup_util.cc
index 4c239582..c29437d 100644
--- a/chrome/installer/setup/setup_util.cc
+++ b/chrome/installer/setup/setup_util.cc
@@ -97,7 +97,7 @@
 // for this mode of install was dropped from ToT in December 2016. Remove any
 // stray bits in the registry leftover from such installs.
 void RemoveBinariesVersionKey(const InstallerState& installer_state) {
-#if !BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#if !BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
   std::wstring path(install_static::GetClientsKeyPath(
       L"{4DC8B4CA-1BDA-483e-B5FA-D3C12E15B62D}"));
@@ -107,7 +107,7 @@
 #endif
   installer::DeleteRegistryKey(installer_state.root_key(), path,
                                KEY_WOW64_32KEY);
-#endif  // !BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#endif  // !BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
 }
 
 void RemoveAppLauncherVersionKey(const InstallerState& installer_state) {
diff --git a/chrome/installer/setup/setup_util_unittest.cc b/chrome/installer/setup/setup_util_unittest.cc
index d6cde0f..ae0892ce 100644
--- a/chrome/installer/setup/setup_util_unittest.cc
+++ b/chrome/installer/setup/setup_util_unittest.cc
@@ -884,7 +884,7 @@
     installer_state_ =
         std::make_unique<FakeInstallerState>(temp_dir_.GetPath());
     // Create the state to be cleared.
-#if !BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#if !BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
     ASSERT_TRUE(base::win::RegKey(HKEY_CURRENT_USER, kBinariesClientsKeyPath,
                                   KEY_WRITE | KEY_WOW64_32KEY)
                     .Valid());
@@ -906,7 +906,7 @@
 
   const InstallerState& installer_state() const { return *installer_state_; }
 
-#if !BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#if !BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
   bool HasBinariesVersionKey() const {
     return base::win::RegKey(HKEY_CURRENT_USER, kBinariesClientsKeyPath,
                              KEY_QUERY_VALUE | KEY_WOW64_32KEY)
@@ -918,7 +918,7 @@
                              KEY_QUERY_VALUE)
         .Valid();
   }
-#endif  // !BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#endif  // !BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
 
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
   bool HasAppLauncherVersionKey() const {
@@ -958,7 +958,7 @@
   }
 #endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
 
-#if !BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#if !BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
   static const wchar_t kBinariesClientsKeyPath[];
   static const wchar_t kCommandExecuteImplClsid[];
 #endif
@@ -980,8 +980,7 @@
 const wchar_t LegacyCleanupsTest::kAppLauncherClientsKeyPath[] =
     L"SOFTWARE\\Google\\Update\\Clients\\"
     L"{FDA71E6F-AC4C-4a00-8B70-9958A68906BF}";
-#elif BUILDFLAG(CHROMIUM_BRANDING) && \
-    !BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#elif BUILDFLAG(CHROMIUM_BRANDING)
 const wchar_t LegacyCleanupsTest::kBinariesClientsKeyPath[] =
     L"SOFTWARE\\Chromium Binaries";
 const wchar_t LegacyCleanupsTest::kCommandExecuteImplClsid[] =
@@ -990,26 +989,26 @@
 
 TEST_F(LegacyCleanupsTest, NoOpOnFailedUpdate) {
   DoLegacyCleanups(installer_state(), INSTALL_FAILED);
-#if !BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#if !BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
   EXPECT_TRUE(HasBinariesVersionKey());
   EXPECT_TRUE(HasCommandExecuteImplClassKey());
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
   EXPECT_TRUE(HasAppLauncherVersionKey());
   EXPECT_TRUE(HasInstallExtensionCommand());
 #endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
-#endif  // !BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#endif  // !BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
 }
 
 TEST_F(LegacyCleanupsTest, Do) {
   DoLegacyCleanups(installer_state(), NEW_VERSION_UPDATED);
-#if !BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#if !BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
   EXPECT_FALSE(HasBinariesVersionKey());
   EXPECT_FALSE(HasCommandExecuteImplClassKey());
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
   EXPECT_FALSE(HasAppLauncherVersionKey());
   EXPECT_FALSE(HasInstallExtensionCommand());
 #endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
-#endif  // !BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#endif  // !BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
 }
 
 }  // namespace installer
diff --git a/chrome/installer/util/beacons_unittest.cc b/chrome/installer/util/beacons_unittest.cc
index 9af6ca71..119ea04d 100644
--- a/chrome/installer/util/beacons_unittest.cc
+++ b/chrome/installer/util/beacons_unittest.cc
@@ -249,7 +249,7 @@
     DefaultBrowserBeaconTest,
     testing::Combine(testing::Values(install_static::CANARY_INDEX),
                      testing::Values("user")));
-#elif BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#elif BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
 // Chrome for Testing is only at user level.
 INSTANTIATE_TEST_SUITE_P(
     ChromeForTesting,
diff --git a/chrome/installer/util/shell_util_interactive_uitest.cc b/chrome/installer/util/shell_util_interactive_uitest.cc
index d4537b4..8a19cfe 100644
--- a/chrome/installer/util/shell_util_interactive_uitest.cc
+++ b/chrome/installer/util/shell_util_interactive_uitest.cc
@@ -164,7 +164,7 @@
   ASSERT_NE(prog_id, GetCurrentDefault(registration.Get(), L".html",
                                        AT_FILEEXTENSION, AL_EFFECTIVE));
 
-#if BUILDFLAG(GOOGLE_CHROME_FOR_TESTING_BRANDING)
+#if BUILDFLAG(USE_INTERNAL_CHROME_FOR_TESTING_ICONS)
   ASSERT_FALSE(ShellUtil::MakeChromeDefaultDirectly(ShellUtil::CURRENT_USER,
                                                     chrome_exe, false));
 #else
diff --git a/chrome/renderer/chrome_render_frame_observer.cc b/chrome/renderer/chrome_render_frame_observer.cc
index a936a62..ff246de6 100644
--- a/chrome/renderer/chrome_render_frame_observer.cc
+++ b/chrome/renderer/chrome_render_frame_observer.cc
@@ -642,7 +642,21 @@
   // Language detection should run only once. Parsing finishes before the page
   // loads, so let's pick that timing.
   if (translate_agent_ &&
-      layout_type == blink::WebMeaningfulLayout::kFinishedParsing) {
+      (layout_type == blink::WebMeaningfulLayout::kFinishedParsing)) {
+    // Under kRetryLanguageDetection, do not attempt language detection if no
+    // page content was captured.
+    if (!base::FeatureList::IsEnabled(translate::kRetryLanguageDetection) ||
+        contents.size()) {
+      translate_agent_->PageCaptured(contents);
+    }
+  }
+  // Under kRetryLanguageDetection, language detection may be attempted
+  // later when the page finishes loading if no content was captured at
+  // kFinishedParsing.
+  if (base::FeatureList::IsEnabled(translate::kRetryLanguageDetection) &&
+      translate_agent_ &&
+      (layout_type == blink::WebMeaningfulLayout::kFinishedLoading) &&
+      !translate_agent_->WasPageContentCapturedForUrl()) {
     translate_agent_->PageCaptured(contents);
   }
 
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 72552ab..6d97190 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -8579,6 +8579,14 @@
     ]
   }
 
+  if (is_linux || is_mac || is_win || is_android) {
+    sources += [
+      "../browser/enterprise/idle/action_runner_unittest.cc",
+      "../browser/enterprise/idle/action_unittest.cc",
+      "../browser/enterprise/idle/idle_timeout_policy_handler_unittest.cc",
+    ]
+  }
+
   if (is_linux || is_mac || is_win) {
     sources += [
       "../browser/accessibility/soda_installer_impl_unittest.cc",
@@ -8590,10 +8598,7 @@
       "../browser/browser_switcher/mock_alternative_browser_driver.cc",
       "../browser/browser_switcher/mock_alternative_browser_driver.h",
       "../browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service_unittest.cc",
-      "../browser/enterprise/idle/action_runner_unittest.cc",
-      "../browser/enterprise/idle/action_unittest.cc",
       "../browser/enterprise/idle/browser_closer_unittest.cc",
-      "../browser/enterprise/idle/idle_timeout_policy_handler_unittest.cc",
       "../browser/enterprise/remote_commands/rotate_attestation_credential_job_unittest.cc",
       "../browser/enterprise/signals/user_delegate_impl_unittest.cc",
       "../browser/net/disk_cache_dir_policy_handler_unittest.cc",
@@ -10768,109 +10773,6 @@
   }
 }
 
-# TODO(crbug.com/1310351): Merge with the block above once fixed.
-if (!is_android) {
-  # The Chrome Enterprise File System Connector requires Google API keys,
-  # and only works on Google Chrome branded builds.
-  # The connectors file system interactive tests are not supported on
-  # ASH and LaCros.
-  if (is_chrome_branded && !is_chromeos) {
-    test("enterprise_connector_file_system_interactive_tests") {
-      use_xvfb = use_xvfb_in_this_config
-      sources = [
-        "//chrome/browser/enterprise/connectors/internal/enterprise_connectors_interactive_uitest_test_accounts.h",
-        "base/interactive_ui_tests_main.cc",
-      ]
-
-      configs += [ "//build/config:precompiled_headers" ]
-
-      data = [
-        "//chrome/test/data/web_page_replay_go_helper_scripts/automation_helper.js",
-        "//third_party/catapult/telemetry/telemetry/bin/",
-        "//third_party/catapult/web_page_replay_go/deterministic.js",
-      ]
-
-      if (is_linux || is_chromeos || is_win) {
-        data_deps = [ "//chrome:packed_resources" ]
-      }
-
-      defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
-
-      ldflags = []
-
-      deps = [
-        ":test_support",
-        ":test_support_ui",
-        "//chrome:packed_resources",
-        "//chrome:resources",
-        "//chrome:strings",
-        "//chrome/browser",
-        "//chrome/browser/devtools",
-        "//chrome/browser/metrics:test_support",
-        "//chrome/renderer",
-        "//chrome/test:sync_integration_test_support",
-        "//components/invalidation/impl:impl",
-        "//components/invalidation/impl:test_support",
-        "//components/policy:chrome_settings_proto_generated_compile",
-        "//components/policy/test_support:test_support",
-        "//components/resources",
-        "//components/security_interstitials/content:security_interstitial_page",
-        "//components/sync",
-        "//components/sync:test_support",
-        "//components/user_manager:user_manager",
-        "//content/test:test_support",
-        "//crypto:test_support",
-        "//google_apis:test_support",
-        "//net",
-        "//net:net_resources",
-        "//net:test_support",
-        "//skia",
-        "//testing/gmock",
-        "//testing/gtest",
-        "//third_party/catapult:telemetry_chrome_test_support",
-        "//third_party/hunspell",
-        "//third_party/icu",
-        "//third_party/libpng",
-        "//ui/base:test_support",
-        "//ui/resources:ui_test_pak",
-        "//ui/web_dialogs:test_support",
-      ]
-
-      if (enable_extensions) {
-        deps += [
-          "//google_apis/common:test_support",
-          "//google_apis/drive",
-        ]
-      }
-
-      if (use_ozone) {
-        deps += [
-          "//ui/ozone",
-          "//ui/platform_window/common",
-        ]
-      }
-
-      if (use_aura) {
-        deps += [ "//ui/aura:test_support" ]
-      }
-
-      if (is_mac) {
-        deps += [ "//chrome/app:command_ids" ]
-      }
-
-      if (is_win) {
-        deps += [
-          "//chrome:other_version",
-          "//chrome/installer/util:strings",
-          "//third_party/webrtc_overrides:webrtc_component",
-          "//third_party/wtl",
-          "//ui/resources",
-        ]
-      }
-    }
-  }
-}
-
 # TOOD(crbug.com/1258253): Merge with block above when it is enabled on Fuchsia.
 if (!is_android) {
   group("telemetry_unittests") {
diff --git a/chrome/test/chromedriver/js/call_function.js b/chrome/test/chromedriver/js/call_function.js
index b1fb1b0..14fcb44 100644
--- a/chrome/test/chromedriver/js/call_function.js
+++ b/chrome/test/chromedriver/js/call_function.js
@@ -326,6 +326,10 @@
       typeof item === 'number' ||
       typeof item === 'string')
     return item;
+  // http://crbug.com/chromedriver/2995: Placed here because some element
+  // (above) are type 'function', so this check must be performed after.
+  if (typeof item === 'function')
+    return {};
   if (isElement(item)) {
     const root = getNodeRootThroughAnyShadows(item);
     const cache = getPageCache(root, w3cEnabled);
@@ -348,17 +352,15 @@
     ret[key] = cache.storeItem(item);
     return ret;
   }
+
+  // TODO(crbug.com/1337415): Implement WindowProxy serialization.
+
+  if (typeof item.toJSON === 'function' &&
+      item.hasOwnProperty('toJSON')) {
+    return item.toJSON();
+  }
   if (isCollection(item))
     return cloneWithCircularCheck(item, seen, jsonSerialize);
-  // http://crbug.com/chromedriver/2995: Placed here because some element
-  // (above) are type 'function', so this check must be performed after.
-  if (typeof item === 'function')
-    return item;
-  // TODO(crbug.com/1337415): Implement WindowProxy serialization.
-  if (typeof item.toJSON === 'function' &&
-      (item.hasOwnProperty('toJSON') ||
-       Object.getPrototypeOf(item).hasOwnProperty('toJSON')))
-    return item.toJSON();
 
   // Deep clone Objects.
   return cloneWithCircularCheck(item, seen, jsonSerialize);
diff --git a/chrome/test/chromedriver/js/call_function_test.html b/chrome/test/chromedriver/js/call_function_test.html
index 8973842..88a574a 100644
--- a/chrome/test/chromedriver/js/call_function_test.html
+++ b/chrome/test/chromedriver/js/call_function_test.html
@@ -230,7 +230,7 @@
   }
   var wrappedHost = wrap(host);
   var wrappedRoot = wrap(root);
-  
+
   // Should handle shadow root as an argument.
   callFunction(func, [wrappedRoot]).then((result) => {
     assertEquals(0, result.status);
@@ -247,17 +247,17 @@
 function testCacheWithShadowDomAttached() {
   clearCache();
   const pageCache = getPageCache();
-  
+
   // Set up something in the shadow DOM.
   var host = document.body.appendChild(document.createElement('div'));
   var root = host.attachShadow({ mode: 'open' });
   var shadowDiv = root.appendChild(document.createElement('div'));
-  
+
   // Test with attached element in shadow DOM.
   var wrappedDiv = wrap(shadowDiv);
   var unwrappedDiv = unwrap(wrappedDiv, pageCache);
   assertEquals(shadowDiv, unwrappedDiv);
-  
+
   document.body.removeChild(host);
 }
 
@@ -279,7 +279,7 @@
   } catch (e) {
     assertEquals(StatusCode.STALE_ELEMENT_REFERENCE, e.code);
   }
-  
+
   document.body.removeChild(host);
 }
 
@@ -302,7 +302,7 @@
 
 // Verify array serialization works when Array.prototype.toJSON is defined.
 // (https://crbug.com/chromedriver/3084)
-function testCallWithArrayToJSON(runner) {
+function testCallWithArrayToJsonProto(runner) {
   clearCache();
 
   Array.prototype.toJSON = () => '["testing"]';
@@ -319,6 +319,24 @@
   runner.waitForAsync();
 }
 
+// Verify array serialization works when own property toJSON is defined.
+// (https://crbug.com/chromedriver/4325)
+function testCallWithArrayToJsonOwn(runner) {
+  clearCache();
+
+  function func() {
+    let result = [1, 2, 3];
+    result.toJSON = () => '["testing"]';
+    return result;
+  }
+  callFunction(func, []).then((result) => {
+    assertEquals(typeof result.value, 'string');
+    assertEquals(result.value, '["testing"]');
+    runner.continueTesting();
+  });
+  runner.waitForAsync();
+}
+
 function testCallWithModifiedObjectProto(runner) {
   var callCount = 0;
   Object.defineProperty(Object.prototype, 'f', {
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json
index 122d3b3..0e47b96 100644
--- a/chrome/test/data/policy/policy_test_cases.json
+++ b/chrome/test/data/policy/policy_test_cases.json
@@ -6101,7 +6101,8 @@
   "GetDisplayMediaSetSelectAllScreensAllowedForUrls": {
     "os": [
       "chromeos_ash",
-      "chromeos_lacros"
+      "chromeos_lacros",
+      "linux"
     ],
     "policy_pref_mapping_tests": [
       {
@@ -20722,10 +20723,10 @@
   },
   "IdleTimeout": {
     "os": [
-      "win",
+      "android",
       "linux",
       "mac",
-      "fuchsia"
+      "win"
     ],
     "policy_pref_mapping_tests": [
       {
@@ -20754,19 +20755,21 @@
   },
   "IdleTimeoutActions": {
     "os": [
-      "win",
+      "android",
       "linux",
-      "mac"
+      "mac",
+      "win"
     ],
     "policy_pref_mapping_tests": [
       {
         "policies": {
           "IdleTimeout": 10,
-          "IdleTimeoutActions": ["close_browsers", "show_profile_picker"]
+          "IdleTimeoutActions": ["clear_browsing_history",
+                                 "clear_download_history"]
         },
         "prefs": {
           "idle_timeout_actions": {
-            "value": [0, 1]
+            "value": [2, 3]
           }
         }
       }
diff --git a/chrome/test/data/webui/bookmarks/BUILD.gn b/chrome/test/data/webui/bookmarks/BUILD.gn
index 601ae68..3879bf2 100644
--- a/chrome/test/data/webui/bookmarks/BUILD.gn
+++ b/chrome/test/data/webui/bookmarks/BUILD.gn
@@ -26,6 +26,7 @@
     "reducers_test.ts",
     "router_test.ts",
     "store_test.js",
+    "test_bookmark_manager_api_proxy.ts",
     "test_bookmarks_api_proxy.ts",
     "test_browser_proxy.ts",
     "test_command_manager.ts",
diff --git a/chrome/test/data/webui/bookmarks/test_bookmark_manager_api_proxy.ts b/chrome/test/data/webui/bookmarks/test_bookmark_manager_api_proxy.ts
new file mode 100644
index 0000000..7132110fe
--- /dev/null
+++ b/chrome/test/data/webui/bookmarks/test_bookmark_manager_api_proxy.ts
@@ -0,0 +1,36 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {BookmarkManagerApiProxy} from 'chrome://bookmarks/bookmarks.js';
+import {FakeChromeEvent} from 'chrome://webui-test/fake_chrome_event.js';
+import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js';
+
+export class TestBookmarkManagerApiProxy extends TestBrowserProxy implements
+    BookmarkManagerApiProxy {
+  onDragEnter = new FakeChromeEvent();
+
+  constructor() {
+    super([
+      'drop',
+      'startDrag',
+      'removeTrees',
+    ]);
+  }
+
+  drop(parentId: string, index?: number) {
+    this.methodCalled('drop', [parentId, index]);
+    return Promise.resolve();
+  }
+
+  startDrag(
+      idList: string[], _dragNodeIndex: number, _isFromTouch: boolean,
+      _x: number, _y: number) {
+    this.methodCalled('startDrag', idList);
+  }
+
+  removeTrees(_idList: string[]) {
+    this.methodCalled('removeTrees');
+    return Promise.resolve();
+  }
+}
diff --git a/chrome/test/data/webui/bookmarks/toolbar_test.ts b/chrome/test/data/webui/bookmarks/toolbar_test.ts
index ff5e2e04..0b5fe9e 100644
--- a/chrome/test/data/webui/bookmarks/toolbar_test.ts
+++ b/chrome/test/data/webui/bookmarks/toolbar_test.ts
@@ -2,12 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {BookmarksToolbarElement, Command} from 'chrome://bookmarks/bookmarks.js';
+import {BookmarkManagerApiProxyImpl, BookmarksToolbarElement, Command} from 'chrome://bookmarks/bookmarks.js';
 import {isMac} from 'chrome://resources/js/platform.js';
 import {pressAndReleaseKeyOn} from 'chrome://resources/polymer/v3_0/iron-test-helpers/mock-interactions.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 
+import {TestBookmarkManagerApiProxy} from './test_bookmark_manager_api_proxy.js';
 import {TestCommandManager} from './test_command_manager.js';
 import {TestStore} from './test_store.js';
 import {createFolder, createItem, getAllFoldersOpenState, replaceBody, testTree} from './test_util.js';
@@ -18,9 +19,8 @@
   let testCommandManager: TestCommandManager;
 
   suiteSetup(function() {
-    chrome.bookmarkManagerPrivate.removeTrees = function() {
-      return Promise.resolve();
-    };
+    const bookmarkManagerApi = new TestBookmarkManagerApiProxy();
+    BookmarkManagerApiProxyImpl.setInstance(bookmarkManagerApi);
   });
 
   setup(function() {
diff --git a/chrome/test/data/webui/chromeos/personalization_app/dynamic_color_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/dynamic_color_element_test.ts
index 09cc30b..eb47779 100644
--- a/chrome/test/data/webui/chromeos/personalization_app/dynamic_color_element_test.ts
+++ b/chrome/test/data/webui/chromeos/personalization_app/dynamic_color_element_test.ts
@@ -7,7 +7,7 @@
 import 'chrome://personalization/strings.m.js';
 import 'chrome://webui-test/mojo_webui_test_support.js';
 
-import {ColorScheme, DynamicColorElement, emptyState, SetColorSchemePrefAction, SetStaticColorPrefAction, ThemeActionName, ThemeObserver} from 'chrome://personalization/js/personalization_app.js';
+import {ColorScheme, DynamicColorElement, emptyState, SetColorSchemeAction, SetSampleColorSchemesAction, SetStaticColorAction, ThemeActionName, ThemeObserver} from 'chrome://personalization/js/personalization_app.js';
 import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js';
 import {CrToggleElement} from 'chrome://resources/cr_elements/cr_toggle/cr_toggle.js';
 import {hexColorToSkColor} from 'chrome://resources/js/color_utils.js';
@@ -110,10 +110,21 @@
 
     const action =
         await personalizationStore.waitForAction(
-            ThemeActionName.SET_COLOR_SCHEME) as SetColorSchemePrefAction;
+            ThemeActionName.SET_COLOR_SCHEME) as SetColorSchemeAction;
     assertEquals(ColorScheme.kTonalSpot, action.colorScheme);
   });
 
+  test('sets sample color schemes in store on first load', async () => {
+    personalizationStore.expectAction(ThemeActionName.SET_SAMPLE_COLOR_SCHEMES);
+
+    await initDynamicColorElement();
+
+    const action = await personalizationStore.waitForAction(
+                       ThemeActionName.SET_SAMPLE_COLOR_SCHEMES) as
+        SetSampleColorSchemesAction;
+    assertEquals(4, action.sampleColorSchemes.length);
+  });
+
   test('sets color scheme data in store on changed', async () => {
     const colorScheme = ColorScheme.kExpressive;
     assertDeepEquals(emptyState(), personalizationStore.data);
@@ -124,7 +135,7 @@
 
     const action =
         await personalizationStore.waitForAction(
-            ThemeActionName.SET_COLOR_SCHEME) as SetColorSchemePrefAction;
+            ThemeActionName.SET_COLOR_SCHEME) as SetColorSchemeAction;
     assertEquals(colorScheme, action.colorScheme);
   });
 
@@ -138,7 +149,7 @@
 
     const action =
         await personalizationStore.waitForAction(
-            ThemeActionName.SET_STATIC_COLOR) as SetStaticColorPrefAction;
+            ThemeActionName.SET_STATIC_COLOR) as SetStaticColorAction;
     assertDeepEquals(staticColor, action.staticColor);
   });
 
@@ -267,7 +278,7 @@
 
     const action =
         await personalizationStore.waitForAction(
-            ThemeActionName.SET_COLOR_SCHEME) as SetColorSchemePrefAction;
+            ThemeActionName.SET_COLOR_SCHEME) as SetColorSchemeAction;
     assertTrue(!!action.colorScheme);
     assertEquals(
         Number(button.dataset['colorSchemeId']!),
@@ -287,7 +298,7 @@
 
     const action =
         await personalizationStore.waitForAction(
-            ThemeActionName.SET_STATIC_COLOR) as SetStaticColorPrefAction;
+            ThemeActionName.SET_STATIC_COLOR) as SetStaticColorAction;
     assertTrue(!!action.staticColor);
     assertDeepEquals(
         hexColorToSkColor(button.dataset['staticColor']!),
diff --git a/chrome/test/data/webui/chromeos/personalization_app/test_theme_interface_provider.ts b/chrome/test/data/webui/chromeos/personalization_app/test_theme_interface_provider.ts
index 5c1485a..84e7d9c9 100644
--- a/chrome/test/data/webui/chromeos/personalization_app/test_theme_interface_provider.ts
+++ b/chrome/test/data/webui/chromeos/personalization_app/test_theme_interface_provider.ts
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 import {ColorScheme, ThemeObserverInterface, ThemeObserverRemote, ThemeProviderInterface} from 'chrome://personalization/js/personalization_app.js';
+import {hexColorToSkColor} from 'chrome://resources/js/color_utils.js';
 import {SkColor} from 'chrome://resources/mojo/skia/public/mojom/skcolor.mojom-webui.js';
 import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js';
 
@@ -15,6 +16,7 @@
       'setColorModeAutoScheduleEnabled',
       'setColorScheme',
       'setStaticColor',
+      'generateSampleColorSchemes',
       'getColorScheme',
       'getStaticColor',
       'isDarkModeEnabled',
@@ -68,6 +70,24 @@
     return Promise.resolve({staticColor: this.staticColor});
   }
 
+  generateSampleColorSchemes() {
+    this.methodCalled('generateSampleColorSchemes');
+    const sampleColorSchemes = [
+      ColorScheme.kTonalSpot,
+      ColorScheme.kExpressive,
+      ColorScheme.kNeutral,
+      ColorScheme.kVibrant,
+    ].map((colorScheme) => {
+      return {
+        scheme: colorScheme,
+        primary: hexColorToSkColor('#ffffff'),
+        secondary: hexColorToSkColor('#ffffff'),
+        tertiary: hexColorToSkColor('#ffffff'),
+      };
+    });
+    return Promise.resolve({sampleColorSchemes});
+  }
+
   isDarkModeEnabled() {
     this.methodCalled('isDarkModeEnabled');
     return Promise.resolve({darkModeEnabled: this.isDarkModeEnabledResponse});
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_test_util.ts b/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_test_util.ts
index 04fe9562..b7e9282 100644
--- a/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_test_util.ts
+++ b/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_test_util.ts
@@ -29,7 +29,7 @@
   return {
     layoutProperties: {
       textAccelerator: {
-        textAccelerator: parts,
+        parts,
       },
     },
     locked,
diff --git a/chrome/test/data/webui/privacy_sandbox/privacy_sandbox_dialog_test.ts b/chrome/test/data/webui/privacy_sandbox/privacy_sandbox_dialog_test.ts
index 447f5a0..1c9847d8 100644
--- a/chrome/test/data/webui/privacy_sandbox/privacy_sandbox_dialog_test.ts
+++ b/chrome/test/data/webui/privacy_sandbox/privacy_sandbox_dialog_test.ts
@@ -323,6 +323,8 @@
     const moreButton: HTMLElement =
         consentStep.shadowRoot!.querySelector('#moreButton')!;
     moreButton.click();
+    await verifyActionOccured(
+        PrivacySandboxPromptAction.CONSENT_MORE_BUTTON_CLICKED);
     await consentStep.whenWasScrolledToBottomForTest();
 
     // After scrolling down, the "More" button is hidden and dialog button are
@@ -538,6 +540,8 @@
     const moreButton: HTMLElement =
         noticeStep.shadowRoot!.querySelector('#moreButton')!;
     moreButton.click();
+    await verifyActionOccured(
+        PrivacySandboxPromptAction.NOTICE_MORE_BUTTON_CLICKED);
     await noticeStep.whenWasScrolledToBottomForTest();
 
     // After scrolling down, the "More" button is hidden and dialog button are
@@ -676,6 +680,8 @@
     const moreButton: HTMLElement =
         page.shadowRoot!.querySelector('#moreButton')!;
     moreButton.click();
+    await verifyActionOccured(
+        PrivacySandboxPromptAction.NOTICE_MORE_BUTTON_CLICKED);
     await page.whenWasScrolledToBottomForTest();
 
     // After scrolling down, the "More" button is hidden and dialog button are
@@ -798,7 +804,7 @@
             </div>
           </div>
           <div id="showMoreOverlay" hidden="[[wasScrolledToBottom]]">
-            <button id="moreButton" on-click="onMoreClicked">More</button>
+            <button id="moreButton" on-click="onMoreClicked_">More</button>
           </div>
         </div>
       `;
diff --git a/chrome/test/data/webui/side_panel/customize_chrome/test_support.ts b/chrome/test/data/webui/side_panel/customize_chrome/test_support.ts
index e7a9fe1..95f1428b 100644
--- a/chrome/test/data/webui/side_panel/customize_chrome/test_support.ts
+++ b/chrome/test/data/webui/side_panel/customize_chrome/test_support.ts
@@ -66,6 +66,7 @@
     foregroundColor: undefined,
     colorPickerIconColor: {value: 0xffff0000},
     colorsManagedByPolicy: false,
+    dailyRefreshCollectionId: undefined,
   };
 }
 
diff --git a/chrome/test/data/webui/side_panel/customize_chrome/themes_test.ts b/chrome/test/data/webui/side_panel/customize_chrome/themes_test.ts
index 7f8c2d5..ad5bf56 100644
--- a/chrome/test/data/webui/side_panel/customize_chrome/themes_test.ts
+++ b/chrome/test/data/webui/side_panel/customize_chrome/themes_test.ts
@@ -5,14 +5,14 @@
 import 'chrome://webui-test/mojo_webui_test_support.js';
 import 'chrome://customize-chrome-side-panel.top-chrome/themes.js';
 
-import {BackgroundCollection, CollectionImage, CustomizeChromePageCallbackRouter, CustomizeChromePageHandlerRemote} from 'chrome://customize-chrome-side-panel.top-chrome/customize_chrome.mojom-webui.js';
+import {BackgroundCollection, CollectionImage, CustomizeChromePageCallbackRouter, CustomizeChromePageHandlerRemote, CustomizeChromePageRemote} from 'chrome://customize-chrome-side-panel.top-chrome/customize_chrome.mojom-webui.js';
 import {CustomizeChromeApiProxy} from 'chrome://customize-chrome-side-panel.top-chrome/customize_chrome_api_proxy.js';
 import {ThemesElement} from 'chrome://customize-chrome-side-panel.top-chrome/themes.js';
 import {assertEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js';
 import {eventToPromise} from 'chrome://webui-test/test_util.js';
 
-import {installMock} from './test_support.js';
+import {createTheme, installMock} from './test_support.js';
 
 function createTestCollection(name: string): BackgroundCollection {
   const testCollection: BackgroundCollection = {
@@ -39,6 +39,7 @@
 
 suite('ThemesTest', () => {
   let themesElement: ThemesElement;
+  let callbackRouterRemote: CustomizeChromePageRemote;
   let handler: TestBrowserProxy<CustomizeChromePageHandlerRemote>;
 
   async function setCollection(collectionName: string, numImages: number) {
@@ -56,6 +57,8 @@
         (mock: CustomizeChromePageHandlerRemote) =>
             CustomizeChromeApiProxy.setInstance(
                 mock, new CustomizeChromePageCallbackRouter()));
+    callbackRouterRemote = CustomizeChromeApiProxy.getInstance()
+                               .callbackRouter.$.bindNewPipeAndPassRemote();
     themesElement = document.createElement('customize-chrome-themes');
     document.body.appendChild(themesElement);
   });
@@ -138,4 +141,60 @@
         'https://preview_5.jpg',
         themes[4]!.querySelector('img')!.getAttribute('auto-src'));
   });
+
+  test('set collection id on refresh daily toggle on', async () => {
+    await setCollection('test_collection', 2);
+
+    // Check that toggling on sets collection id to current collection id.
+    themesElement.$.refreshDailyToggle.click();
+    const setDailyRefreshCollectionIdCalled =
+        handler.whenCalled('setDailyRefreshCollectionId');
+    const id = await setDailyRefreshCollectionIdCalled;
+    assertEquals(id, themesElement.selectedCollection!.id);
+  });
+
+  test('set empty collection id on refresh daily toggle off', async () => {
+    await setCollection('test_collection', 2);
+
+    // Turn toggle on.
+    const theme = createTheme();
+    theme.dailyRefreshCollectionId = themesElement.selectedCollection!.id;
+    callbackRouterRemote.setTheme(theme);
+    await callbackRouterRemote.$.flushForTesting();
+    assertTrue(themesElement.$.refreshDailyToggle.checked);
+
+    // Check that toggling off sets collection id to empty string.
+    themesElement.$.refreshDailyToggle.click();
+    const setDailyRefreshCollectionIdCalled =
+        handler.whenCalled('setDailyRefreshCollectionId');
+    const id = await setDailyRefreshCollectionIdCalled;
+    assertEquals(id, '');
+  });
+
+  test(
+      'refresh daily toggle is on if current collection id matches',
+      async () => {
+        await setCollection('test_collection', 2);
+
+        // Check that toggle isn't on if refresh daily is undefined.
+        let theme = createTheme();
+        callbackRouterRemote.setTheme(theme);
+        await callbackRouterRemote.$.flushForTesting();
+        assertTrue(!themesElement.$.refreshDailyToggle.checked);
+
+        // Check that toggle isn't on if refresh daily is a different
+        // collection.
+        theme = createTheme();
+        theme.dailyRefreshCollectionId = 'different_collection';
+        callbackRouterRemote.setTheme(theme);
+        await callbackRouterRemote.$.flushForTesting();
+        assertTrue(!themesElement.$.refreshDailyToggle.checked);
+
+        // Check that toggle is on if refresh daily matches current collection.
+        theme = createTheme();
+        theme.dailyRefreshCollectionId = themesElement.selectedCollection!.id;
+        callbackRouterRemote.setTheme(theme);
+        await callbackRouterRemote.$.flushForTesting();
+        assertTrue(themesElement.$.refreshDailyToggle.checked);
+      });
 });
diff --git a/chrome/test/payments/payment_request_test_controller_desktop.cc b/chrome/test/payments/payment_request_test_controller_desktop.cc
index fd1d340..2a671c1 100644
--- a/chrome/test/payments/payment_request_test_controller_desktop.cc
+++ b/chrome/test/payments/payment_request_test_controller_desktop.cc
@@ -72,6 +72,7 @@
   void OnConnectionTerminated() override {
     controller_->OnConnectionTerminated();
   }
+  void OnPayCalled() override {}
   void OnAbortCalled() override { controller_->OnAbortCalled(); }
   void OnCompleteCalled() override { controller_->OnCompleteCalled(); }
 
diff --git a/chromecast/cast_core/README.md b/chromecast/cast_core/README.md
index ba52e24..465eb6e 100644
--- a/chromecast/cast_core/README.md
+++ b/chromecast/cast_core/README.md
@@ -31,11 +31,12 @@
 Running the Cast Web Runtime on Linux can be done with the following steps:
 
 1. Build the Cast Web Runtime using the above flags
-2. Build Cast Core following instructions [here](go/cast-core-on-glinux#build).
-3. [Run](go/cast-core-on-glinux#run) the Cast Core and Platform Service
-applications built in step 2. Note that if it is your first time running Cast
-Core you will need to
-[generate certificates](go/cast-core-on-glinux#certificates).
+2. Build Cast Core following instructions
+[here](https://goto.google.com/cast-core-on-glinux#build).
+3. [Run](https://goto.google.com/cast-core-on-glinux#run) the Cast Core and
+Platform Service applications built in step 2. Note that if it is your first
+time running Cast Core you will need to
+[generate certificates](https://goto.google.com/cast-core-on-glinux#certificates).
 4. Run the `core_runtime_simple` application built in step 1. The runtime should
 immediately be registered with Cast Core.
 5. Cast from a Chrome instance running on the local machine. It may take a few
diff --git a/chromeos/ash/components/dbus/userdataauth/fake_userdataauth_client.cc b/chromeos/ash/components/dbus/userdataauth/fake_userdataauth_client.cc
index d75fe7967..ad7a567 100644
--- a/chromeos/ash/components/dbus/userdataauth/fake_userdataauth_client.cc
+++ b/chromeos/ash/components/dbus/userdataauth/fake_userdataauth_client.cc
@@ -181,6 +181,7 @@
             data.set_label(std::move(label));
             data.add_challenge_response_key()->set_public_key_spki_der(
                 smart_card.public_key_spki_der);
+            // TODO (b/241259026): populate algorithms.
             return data;
           },
           [&](const KioskFactor& kiosk) {
@@ -229,8 +230,7 @@
           [&](const SmartCardFactor& smart_card) {
             user_data_auth::AuthFactor result;
             result.set_label(std::move(label));
-            result.set_type(
-                user_data_auth::AUTH_FACTOR_TYPE_CRYPTOHOME_RECOVERY);
+            result.set_type(user_data_auth::AUTH_FACTOR_TYPE_SMART_CARD);
             result.mutable_smart_card_metadata()->set_public_key_spki_der(
                 smart_card.public_key_spki_der);
             return result;
@@ -299,8 +299,8 @@
     case user_data_auth::AUTH_FACTOR_TYPE_CRYPTOHOME_RECOVERY:
       return {label, RecoveryFactor{}};
     case user_data_auth::AUTH_FACTOR_TYPE_SMART_CARD: {
-      std::string t = factor.smart_card_metadata().public_key_spki_der();
-      return {label, SmartCardFactor{.public_key_spki_der = t}};
+      std::string key = factor.smart_card_metadata().public_key_spki_der();
+      return {label, SmartCardFactor{.public_key_spki_der = key}};
     }
     default:
       NOTREACHED();
@@ -957,8 +957,7 @@
   // fixed, we explicitly add keys here.
   if (user_exists) {
     if (is_kiosk) {
-      // See kCryptohomePublicMountLabel.
-      std::string kiosk_label = "publicmount";
+      std::string kiosk_label = kCryptohomePublicMountLabel;
       cryptohome::KeyData kiosk_key;
       kiosk_key.set_label(kiosk_label);
       kiosk_key.set_type(cryptohome::KeyData::KEY_TYPE_KIOSK);
diff --git a/chromeos/ash/components/phonehub/message_sender_impl.cc b/chromeos/ash/components/phonehub/message_sender_impl.cc
index 27b3a97..d259926 100644
--- a/chromeos/ash/components/phonehub/message_sender_impl.cc
+++ b/chromeos/ash/components/phonehub/message_sender_impl.cc
@@ -54,13 +54,6 @@
   proto::CrosState request;
   request.set_notification_setting(is_notification_enabled);
   request.set_camera_roll_setting(is_camera_roll_enabled);
-  if (features::IsPhoneHubMonochromeNotificationIconsEnabled()) {
-    // Updated Chromebooks should always use the new flag, but a flag is still
-    // necessary to identify end-of-support Chromebooks so the phone can know
-    // to send backwards-compatible messages.
-    request.set_notification_icon_styling(
-        proto::NotificationIconStyling::ICON_STYLE_MONOCHROME_SMALL_ICON);
-  }
 
   if (attestation_certs != nullptr) {
     proto::AttestationData* attestation_data =
diff --git a/chromeos/ash/components/phonehub/message_sender_unittest.cc b/chromeos/ash/components/phonehub/message_sender_unittest.cc
index 286e619..c904bf8 100644
--- a/chromeos/ash/components/phonehub/message_sender_unittest.cc
+++ b/chromeos/ash/components/phonehub/message_sender_unittest.cc
@@ -67,11 +67,6 @@
       proto::NotificationSetting::NOTIFICATIONS_ON);
   request.set_camera_roll_setting(proto::CameraRollSetting::CAMERA_ROLL_OFF);
   request.set_allocated_attestation_data(nullptr);
-  if (features::IsPhoneHubMonochromeNotificationIconsEnabled()) {
-    request.set_notification_icon_styling(
-        proto::NotificationIconStyling::ICON_STYLE_MONOCHROME_SMALL_ICON);
-  }
-
   message_sender_->SendCrosState(/*notification_enabled=*/true,
                                  /*camera_roll_enabled=*/false,
                                  /*certs=*/nullptr);
@@ -87,10 +82,6 @@
   request.mutable_attestation_data()->set_type(
       proto::AttestationData::CROS_SOFT_BIND_CERT_CHAIN);
   request.mutable_attestation_data()->add_certificates("certificate");
-  if (features::IsPhoneHubMonochromeNotificationIconsEnabled()) {
-    request.set_notification_icon_styling(
-        proto::NotificationIconStyling::ICON_STYLE_MONOCHROME_SMALL_ICON);
-  }
 
   std::vector<std::string> certificates = {"certificate"};
 
diff --git a/chromeos/ash/components/phonehub/notification_processor.cc b/chromeos/ash/components/phonehub/notification_processor.cc
index 5f32b6b..23895fe 100644
--- a/chromeos/ash/components/phonehub/notification_processor.cc
+++ b/chromeos/ash/components/phonehub/notification_processor.cc
@@ -28,9 +28,10 @@
 
 absl::optional<SkColor> getMonochromeIconColor(const proto::Notification& proto,
                                                const gfx::Image& icon) {
-  if (icon.IsEmpty() || !proto.origin_app().has_icon_color()) {
+  if (icon.IsEmpty() || !proto.origin_app().has_monochrome_icon_color()) {
     return absl::nullopt;
   }
+
   if (proto.origin_app().package_name() == kMessagesPackageName) {
     // The notification color supplied by the Messages app (Bugle) is based
     // on light/dark mode of the phone, not the Chromebook, with no way to
@@ -38,9 +39,10 @@
     // a fixed color. See conversation at b/207089786 for more details.
     return kMessagesOverrideColor;
   }
-  return SkColorSetRGB(proto.origin_app().icon_color().red(),
-                       proto.origin_app().icon_color().green(),
-                       proto.origin_app().icon_color().blue());
+
+  return SkColorSetRGB(proto.origin_app().monochrome_icon_color().red(),
+                       proto.origin_app().monochrome_icon_color().green(),
+                       proto.origin_app().monochrome_icon_color().blue());
 }
 
 Notification::Importance GetNotificationImportanceFromProto(
@@ -77,6 +79,11 @@
   return false;
 }
 
+bool IsMonochromeIconEnabled(const proto::Notification& notification_proto) {
+  return features::IsPhoneHubMonochromeNotificationIconsEnabled() &&
+         notification_proto.origin_app().has_monochrome_icon_mask();
+}
+
 Notification CreateInternalNotification(const proto::Notification& proto,
                                         const gfx::Image& icon,
                                         const gfx::Image& shared_image,
@@ -143,9 +150,7 @@
   if (!contact_image.IsEmpty())
     opt_contact_image = contact_image;
 
-  bool icon_is_monochrome =
-      proto.origin_app().icon_styling() ==
-      proto::NotificationIconStyling::ICON_STYLE_MONOCHROME_SMALL_ICON;
+  bool icon_is_monochrome = IsMonochromeIconEnabled(proto);
   absl::optional<SkColor> icon_color =
       icon_is_monochrome ? getMonochromeIconColor(proto, icon) : absl::nullopt;
 
@@ -207,8 +212,14 @@
 
     processed_notification_protos.emplace_back(proto);
 
-    decode_image_requests.emplace_back(
-        proto.id(), NotificationImageField::kIcon, proto.origin_app().icon());
+    if (IsMonochromeIconEnabled(proto)) {
+      decode_image_requests.emplace_back(
+          proto.id(), NotificationImageField::kIcon,
+          proto.origin_app().monochrome_icon_mask());
+    } else {
+      decode_image_requests.emplace_back(
+          proto.id(), NotificationImageField::kIcon, proto.origin_app().icon());
+    }
 
     if (!proto.shared_image().empty()) {
       decode_image_requests.emplace_back(proto.id(),
diff --git a/chromeos/ash/components/phonehub/notification_processor_unittest.cc b/chromeos/ash/components/phonehub/notification_processor_unittest.cc
index 12d4d06..7cfcffb 100644
--- a/chromeos/ash/components/phonehub/notification_processor_unittest.cc
+++ b/chromeos/ash/components/phonehub/notification_processor_unittest.cc
@@ -190,14 +190,13 @@
     proto::Notification notification = CreateNewInlineReplyableNotification(
         notification_id, inline_reply_id, icon);
     proto::App* origin_app = notification.mutable_origin_app();
-    origin_app->set_icon_styling(
-        proto::NotificationIconStyling::ICON_STYLE_MONOCHROME_SMALL_ICON);
+    origin_app->set_monochrome_icon_mask(icon);
     if (icon_color != absl::nullopt) {
       auto color_rgb = std::make_unique<proto::ColorRgb>();
       color_rgb->set_red(SkColorGetR(*icon_color));
       color_rgb->set_green(SkColorGetG(*icon_color));
       color_rgb->set_blue(SkColorGetB(*icon_color));
-      origin_app->set_allocated_icon_color(color_rgb.release());
+      origin_app->set_allocated_monochrome_icon_color(color_rgb.release());
     }
     return notification;
   }
@@ -323,7 +322,6 @@
 
   const Notification* notification =
       fake_notification_manager()->GetNotification(kNotificationIdA);
-  EXPECT_FALSE(notification->app_metadata().icon_is_monochrome);
   EXPECT_TRUE(gfx::test::AreImagesEqual(notification->app_metadata().icon,
                                         TestImage()));
   EXPECT_FALSE(notification->app_metadata().icon_color.has_value());
diff --git a/chromeos/ash/components/phonehub/phone_status_processor.cc b/chromeos/ash/components/phonehub/phone_status_processor.cc
index 5a58f82..a098fd2 100644
--- a/chromeos/ash/components/phonehub/phone_status_processor.cc
+++ b/chromeos/ash/components/phonehub/phone_status_processor.cc
@@ -471,9 +471,7 @@
     // let's move it outside of the Notification class.s2
     apps_list.emplace_back(Notification::AppMetadata(
         base::UTF8ToUTF16(app.visible_name()), app.package_name(), image,
-        absl::nullopt,
-        app.icon_styling() ==
-            proto::NotificationIconStyling::ICON_STYLE_MONOCHROME_SMALL_ICON,
+        /* icon_color = */ absl::nullopt, /* icon_is_monochrome = */ false,
         app.user_id(), app.app_streamability_status()));
     std::string key = app.package_name() + base::NumberToString(app.user_id());
     decoding_data_list->emplace_back(
diff --git a/chromeos/ash/components/phonehub/proto/phonehub_api.proto b/chromeos/ash/components/phonehub/proto/phonehub_api.proto
index f0917e03..e2b78044 100644
--- a/chromeos/ash/components/phonehub/proto/phonehub_api.proto
+++ b/chromeos/ash/components/phonehub/proto/phonehub_api.proto
@@ -55,14 +55,6 @@
   CAMERA_ROLL_ON = 1;
 }
 
-enum NotificationIconStyling {
-  // Use multicolor Android app icon logic. Keep as the zero default for
-  // backwards compatibility.
-  ICON_STYLE_DEFAULT_LEGACY_APP_ICON = 0;
-  // Use monochrome icon styling logic.
-  ICON_STYLE_MONOCHROME_SMALL_ICON = 1;
-}
-
 enum AppStreamabilityStatus {
   STREAMABLE = 0;
   BLOCK_LISTED = 1;
@@ -247,12 +239,12 @@
   bytes icon = 3;
   int64 user_id = 4;
 
-  NotificationIconStyling icon_styling = 5;
-  // Optionally used only when icon_styling is ICON_STYLE_MONOCHROME_SMALL_ICON.
   // When unset, the ChromeOS side uses the system theme's default color.
-  ColorRgb icon_color = 6;
-
+  ColorRgb monochrome_icon_color = 6;
   AppStreamabilityStatus app_streamability_status = 7;
+  optional bytes monochrome_icon_mask = 8;
+
+  reserved 5;  // deprecated icon_stying field.
 }
 
 // Data required to verify the remote device.
@@ -276,10 +268,10 @@
 message CrosState {
   NotificationSetting notification_setting = 1;
   CameraRollSetting camera_roll_setting = 2;
-  // Optional in the case of un-updated phones.
-  NotificationIconStyling notification_icon_styling = 3;
   // Optional for older Chromebooks pre-attestation.
   AttestationData attestation_data = 4;
+
+  reserved 3;  // deprecated notification_icon_styling field.
 }
 
 message Action {
diff --git a/chromeos/components/onc/onc_utils.cc b/chromeos/components/onc/onc_utils.cc
index 0275507..a15e9d3 100644
--- a/chromeos/components/onc/onc_utils.cc
+++ b/chromeos/components/onc/onc_utils.cc
@@ -13,6 +13,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/notreached.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/values.h"
 #include "chromeos/components/onc/onc_mapper.h"
 #include "chromeos/components/onc/onc_signature.h"
 #include "chromeos/components/onc/onc_validator.h"
@@ -277,11 +278,12 @@
                                 const std::string& key_guid_ref,
                                 const std::string& key_pem_list,
                                 base::Value* onc_object) {
-  if (onc_object->FindKey(key_guid_refs)) {
-    if (onc_object->FindKey(key_guid_ref)) {
+  base::Value::Dict& onc_dict = onc_object->GetDict();
+  if (onc_dict.contains(key_guid_refs)) {
+    if (onc_dict.contains(key_guid_ref)) {
       LOG(ERROR) << "Found both " << key_guid_refs << " and " << key_guid_ref
                  << ". Ignoring and removing the latter.";
-      onc_object->RemoveKey(key_guid_ref);
+      onc_dict.Remove(key_guid_ref);
     }
     return ResolveCertRefList(certs_by_guid, key_guid_refs, key_pem_list,
                               onc_object);
diff --git a/chromeos/profiles/arm.afdo.newest.txt b/chromeos/profiles/arm.afdo.newest.txt
index 40505db6..e4a51e88 100644
--- a/chromeos/profiles/arm.afdo.newest.txt
+++ b/chromeos/profiles/arm.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-arm-none-110-5481.21-1673266524-benchmark-110.0.5481.34-r1-redacted.afdo.xz
+chromeos-chrome-arm-none-111-5481.21-1673265798-benchmark-111.0.5534.0-r1-redacted.afdo.xz
diff --git a/chromeos/profiles/atom.afdo.newest.txt b/chromeos/profiles/atom.afdo.newest.txt
index 0363922..c37ff97 100644
--- a/chromeos/profiles/atom.afdo.newest.txt
+++ b/chromeos/profiles/atom.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-atom-110-5481.21-1673266524-benchmark-110.0.5481.34-r1-redacted.afdo.xz
+chromeos-chrome-amd64-atom-111-5464.0-1672659638-benchmark-111.0.5514.0-r1-redacted.afdo.xz
diff --git a/chromeos/profiles/bigcore.afdo.newest.txt b/chromeos/profiles/bigcore.afdo.newest.txt
index e2c5e731..f0e2901 100644
--- a/chromeos/profiles/bigcore.afdo.newest.txt
+++ b/chromeos/profiles/bigcore.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-bigcore-110-5481.21-1673260884-benchmark-110.0.5481.34-r1-redacted.afdo.xz
+chromeos-chrome-amd64-bigcore-111-5464.0-1672657853-benchmark-111.0.5514.0-r1-redacted.afdo.xz
diff --git a/chromeos/ui/frame/caption_buttons/frame_size_button.cc b/chromeos/ui/frame/caption_buttons/frame_size_button.cc
index c6fe7ad..1c85eeb 100644
--- a/chromeos/ui/frame/caption_buttons/frame_size_button.cc
+++ b/chromeos/ui/frame/caption_buttons/frame_size_button.cc
@@ -25,6 +25,7 @@
 #include "ui/gfx/animation/slide_animation.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/geometry/vector2d.h"
+#include "ui/views/animation/animation_delegate_views.h"
 #include "ui/views/animation/compositor_animation_runner.h"
 #include "ui/views/widget/widget.h"
 
@@ -87,51 +88,50 @@
 
 }  // namespace
 
-// This class controls animating a pie on a parent button which indicates when
+// This view controls animating a pie on a parent button which indicates when
 // long press or long hover will end.
-class FrameSizeButton::PieAnimation : public gfx::SlideAnimation,
-                                      public gfx::AnimationDelegate {
+class FrameSizeButton::PieAnimationView : public views::View,
+                                          public views::AnimationDelegateViews {
  public:
-  PieAnimation(base::TimeDelta duration,
-               base::OnceClosure on_animation_canceled,
-               base::OnceClosure on_animation_ended,
-               FrameSizeButton* button)
-      : gfx::SlideAnimation(this),
-        on_animation_canceled_(std::move(on_animation_canceled)),
-        on_animation_ended_(std::move(on_animation_ended)),
-        button_(button) {
+  explicit PieAnimationView(FrameSizeButton* button)
+      : views::AnimationDelegateViews(this), button_(button) {
+    SetCanProcessEventsWithinSubtree(false);
+    animation_.SetTweenType(gfx::Tween::LINEAR);
+  }
+  PieAnimationView(const PieAnimationView&) = delete;
+  PieAnimationView& operator=(const PieAnimationView&) = delete;
+  ~PieAnimationView() override = default;
+
+  void Start(base::TimeDelta duration, MultitaskMenuEntryType entry_type) {
+    entry_type_ = entry_type;
+
+    animation_.Reset(0.0);
     // `SlideAnimation` is unaffected by debug tools such as
     // "--ui-slow-animations" flag, so manually multiply the duration here.
-    SetSlideDuration(
+    animation_.SetSlideDuration(
         ui::ScopedAnimationDurationScaleMode::duration_multiplier() * duration);
-    SetTweenType(gfx::Tween::LINEAR);
-
-    // Use a runner synced with the compositor.
-    gfx::AnimationContainer* container = new gfx::AnimationContainer();
-    container->SetAnimationRunner(
-        std::make_unique<views::CompositorAnimationRunner>(
-            button_->GetWidget()));
-    SetContainer(container);
-
-    Show();
+    animation_.Show();
   }
 
-  PieAnimation(const PieAnimation&) = delete;
-  PieAnimation& operator=(const PieAnimation&) = delete;
+  void Stop() {
+    animation_.Reset(0.0);
+    SchedulePaint();
+  }
 
-  ~PieAnimation() override = default;
-
-  void Paint(gfx::Canvas* canvas) {
-    // Use the bounds of the inkdrop.
-    gfx::Rect bounds = button_->GetLocalBounds();
-    bounds.Inset(button_->GetInkdropInsets(bounds.size()));
+  // views::View:
+  void OnPaint(gfx::Canvas* canvas) override {
+    const double animation_value = animation_.GetCurrentValue();
+    if (animation_value == 0.0) {
+      return;
+    }
 
     // The pie is a filled arc which starts at the top and sweeps around
     // clockwise.
     const SkScalar start_angle = -90.f;
-    const SkScalar sweep_angle = 360.f * GetCurrentValue();
+    const SkScalar sweep_angle = 360.f * animation_value;
 
     SkPath path;
+    const gfx::Rect bounds = GetLocalBounds();
     path.moveTo(bounds.CenterPoint().x(), bounds.CenterPoint().y());
     path.arcTo(gfx::RectToSkRect(bounds), start_angle, sweep_angle,
                /*forceMoveTo=*/false);
@@ -144,23 +144,23 @@
     canvas->DrawPath(path, flags);
   }
 
-  // gfx::AnimationDelegate:
+  // views::AnimationDelegateViews:
   void AnimationEnded(const gfx::Animation* animation) override {
-    button_->SchedulePaint();
-    std::move(on_animation_ended_).Run();
+    SchedulePaint();
+    button_->ShowMultitaskMenu(entry_type_);
   }
 
   void AnimationProgressed(const gfx::Animation* animation) override {
-    button_->SchedulePaint();
-  }
-
-  void AnimationCanceled(const gfx::Animation* animation) override {
-    std::move(on_animation_canceled_).Run();
+    SchedulePaint();
   }
 
  private:
-  base::OnceClosure on_animation_canceled_;
-  base::OnceClosure on_animation_ended_;
+  gfx::SlideAnimation animation_{this};
+
+  // Tracks the entry type that triggered the latests pie animation. Used for
+  // recording metrics once the menu is shown.
+  MultitaskMenuEntryType entry_type_ =
+      MultitaskMenuEntryType::kFrameSizeButtonHover;
 
   // The button `this` is associated with. Unowned.
   raw_ptr<FrameSizeButton> button_;
@@ -220,6 +220,11 @@
       delegate_(delegate),
       set_buttons_to_snap_mode_delay_ms_(kSetButtonsToSnapModeDelayMs) {
   display_observer_.emplace(this);
+
+  if (chromeos::wm::features::IsFloatWindowEnabled()) {
+    pie_animation_view_ =
+        AddChildView(std::make_unique<PieAnimationView>(this));
+  }
 }
 
 FrameSizeButton::~FrameSizeButton() = default;
@@ -264,7 +269,7 @@
 
 bool FrameSizeButton::OnMousePressed(const ui::MouseEvent& event) {
   // Note that this triggers `StateChanged()`, and we want the changes to
-  // `pie_animation_` below to come after `StateChanged()`.
+  // `pie_animation_view_` below to come after `StateChanged()`.
   views::FrameCaptionButton::OnMousePressed(event);
 
   if (IsTriggerableEvent(event)) {
@@ -352,6 +357,8 @@
 }
 
 void FrameSizeButton::StateChanged(views::Button::ButtonState old_state) {
+  views::FrameCaptionButton::StateChanged(old_state);
+
   if (!chromeos::wm::features::IsFloatWindowEnabled())
     return;
 
@@ -360,20 +367,27 @@
     StartPieAnimation(kPieAnimationHoverDuration,
                       MultitaskMenuEntryType::kFrameSizeButtonHover);
   } else if (old_state == views::Button::STATE_HOVERED) {
-    pie_animation_.reset();
+    DCHECK(pie_animation_view_);
+    pie_animation_view_->Stop();
   }
 }
 
-void FrameSizeButton::PaintButtonContents(gfx::Canvas* canvas) {
-  if (pie_animation_)
-    pie_animation_->Paint(canvas);
+void FrameSizeButton::Layout() {
+  if (pie_animation_view_) {
+    // Use the bounds of the inkdrop.
+    gfx::Rect bounds = GetLocalBounds();
+    bounds.Inset(GetInkdropInsets(bounds.size()));
+    pie_animation_view_->SetBoundsRect(bounds);
+  }
 
-  views::FrameCaptionButton::PaintButtonContents(canvas);
+  views::FrameCaptionButton::Layout();
 }
 
 void FrameSizeButton::OnDisplayTabletStateChanged(display::TabletState state) {
   if (state == display::TabletState::kEnteringTabletMode) {
-    pie_animation_.reset();
+    if (pie_animation_view_) {
+      pie_animation_view_->Stop();
+    }
     set_buttons_to_snap_mode_timer_.Stop();
   }
 }
@@ -397,14 +411,8 @@
     return;
   }
 
-  base::OnceClosure cancel_animation = base::BindOnce(
-      &FrameSizeButton::DestroyPieAnimation, base::Unretained(this));
-  base::OnceClosure show_multitask_menu =
-      base::BindOnce(&FrameSizeButton::OnPieAnimationCompleted,
-                     base::Unretained(this), entry_type);
-  pie_animation_ =
-      std::make_unique<PieAnimation>(duration, std::move(cancel_animation),
-                                     std::move(show_multitask_menu), this);
+  DCHECK(pie_animation_view_);
+  pie_animation_view_->Start(duration, entry_type);
 }
 
 void FrameSizeButton::AnimateButtonsToSnapMode() {
@@ -514,21 +522,13 @@
 void FrameSizeButton::SetButtonsToNormalMode(
     FrameSizeButtonDelegate::Animate animate) {
   in_snap_mode_ = false;
-  pie_animation_.reset();
+  if (pie_animation_view_) {
+    pie_animation_view_->Stop();
+  }
   set_buttons_to_snap_mode_timer_.Stop();
   delegate_->SetButtonsToNormal(animate);
 }
 
-void FrameSizeButton::OnPieAnimationCompleted(
-    MultitaskMenuEntryType entry_type) {
-  ShowMultitaskMenu(entry_type);
-  pie_animation_.reset();
-}
-
-void FrameSizeButton::DestroyPieAnimation() {
-  pie_animation_.reset();
-}
-
 BEGIN_METADATA(FrameSizeButton, views::FrameCaptionButton)
 END_METADATA
 
diff --git a/chromeos/ui/frame/caption_buttons/frame_size_button.h b/chromeos/ui/frame/caption_buttons/frame_size_button.h
index eaf6fdd..36c4f92 100644
--- a/chromeos/ui/frame/caption_buttons/frame_size_button.h
+++ b/chromeos/ui/frame/caption_buttons/frame_size_button.h
@@ -58,7 +58,7 @@
   // preview will be deleted and the button will be set back to its normal mode.
   void CancelSnap();
 
-  // views::Button:
+  // views::FrameCaptionButton:
   bool OnMousePressed(const ui::MouseEvent& event) override;
   bool OnMouseDragged(const ui::MouseEvent& event) override;
   void OnMouseReleased(const ui::MouseEvent& event) override;
@@ -66,7 +66,7 @@
   void OnMouseMoved(const ui::MouseEvent& event) override;
   void OnGestureEvent(ui::GestureEvent* event) override;
   void StateChanged(views::Button::ButtonState old_state) override;
-  void PaintButtonContents(gfx::Canvas* canvas) override;
+  void Layout() override;
 
   // display::DisplayObserver:
   void OnDisplayTabletStateChanged(display::TabletState state) override;
@@ -78,7 +78,7 @@
   bool in_snap_mode_for_testing() { return in_snap_mode_; }
 
  private:
-  class PieAnimation;
+  class PieAnimationView;
   class SnappingWindowObserver;
 
   // Starts |set_buttons_to_snap_mode_timer_|.
@@ -116,12 +116,6 @@
   // whether the buttons should animate back to their original icons.
   void SetButtonsToNormalMode(FrameSizeButtonDelegate::Animate animate);
 
-  // Show Multitask Menu when pie animation is completed, where `entry_type`
-  // indicates the method the user started and completed this animation and show
-  // the menu.
-  void OnPieAnimationCompleted(MultitaskMenuEntryType entry_type);
-  void DestroyPieAnimation();
-
   // Not owned.
   raw_ptr<FrameSizeButtonDelegate> delegate_;
   raw_ptr<MultitaskMenu> multitask_menu_ = nullptr;
@@ -141,8 +135,9 @@
   base::OneShotTimer set_buttons_to_snap_mode_timer_;
 
   // Creates an animation to add indication to when long hover and long press to
-  // show multitask menu and snap buttons will trigger.
-  std::unique_ptr<PieAnimation> pie_animation_;
+  // show multitask menu and snap buttons will trigger. The pointer is owned by
+  // the views hierarchy.
+  raw_ptr<PieAnimationView> pie_animation_view_ = nullptr;
 
   // Whether the buttons adjacent to the size button snap the window left and
   // right.
diff --git a/components/browsing_topics/browsing_topics_calculator_unittest.cc b/components/browsing_topics/browsing_topics_calculator_unittest.cc
index 3afe983..41b89acd 100644
--- a/components/browsing_topics/browsing_topics_calculator_unittest.cc
+++ b/components/browsing_topics/browsing_topics_calculator_unittest.cc
@@ -23,7 +23,7 @@
 #include "components/optimization_guide/core/test_model_info_builder.h"
 #include "components/optimization_guide/core/test_optimization_guide_model_provider.h"
 #include "components/privacy_sandbox/privacy_sandbox_prefs.h"
-#include "components/privacy_sandbox/privacy_sandbox_settings.h"
+#include "components/privacy_sandbox/privacy_sandbox_settings_impl.h"
 #include "components/privacy_sandbox/privacy_sandbox_test_util.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
 #include "components/ukm/test_ukm_recorder.h"
@@ -70,7 +70,7 @@
     privacy_sandbox_delegate->SetUpIsIncognitoProfileResponse(
         /*incognito=*/false);
     privacy_sandbox_settings_ =
-        std::make_unique<privacy_sandbox::PrivacySandboxSettings>(
+        std::make_unique<privacy_sandbox::PrivacySandboxSettingsImpl>(
             std::move(privacy_sandbox_delegate),
             host_content_settings_map_.get(), cookie_settings_, &prefs_);
     privacy_sandbox_settings_->SetAllPrivacySandboxAllowedForTesting();
diff --git a/components/browsing_topics/browsing_topics_service_impl_unittest.cc b/components/browsing_topics/browsing_topics_service_impl_unittest.cc
index 60fde810..a97492a 100644
--- a/components/browsing_topics/browsing_topics_service_impl_unittest.cc
+++ b/components/browsing_topics/browsing_topics_service_impl_unittest.cc
@@ -27,7 +27,7 @@
 #include "components/optimization_guide/content/browser/test_page_content_annotator.h"
 #include "components/optimization_guide/core/test_model_info_builder.h"
 #include "components/privacy_sandbox/privacy_sandbox_prefs.h"
-#include "components/privacy_sandbox/privacy_sandbox_settings.h"
+#include "components/privacy_sandbox/privacy_sandbox_settings_impl.h"
 #include "components/privacy_sandbox/privacy_sandbox_test_util.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
 #include "components/ukm/test_ukm_recorder.h"
@@ -198,7 +198,7 @@
     privacy_sandbox_delegate->SetUpIsIncognitoProfileResponse(
         /*incognito=*/false);
     privacy_sandbox_settings_ =
-        std::make_unique<privacy_sandbox::PrivacySandboxSettings>(
+        std::make_unique<privacy_sandbox::PrivacySandboxSettingsImpl>(
             std::move(privacy_sandbox_delegate),
             host_content_settings_map_.get(), cookie_settings_, &prefs_);
     privacy_sandbox_settings_->SetAllPrivacySandboxAllowedForTesting();
diff --git a/components/feature_engagement/README.md b/components/feature_engagement/README.md
index f855d2e..8c96563 100644
--- a/components/feature_engagement/README.md
+++ b/components/feature_engagement/README.md
@@ -880,6 +880,11 @@
 
 ```c++
 BASE_DECLARE_FEATURE(kIPHPasswordInfobarFeature);
+```
+
+In `//components/feature_engagement/public/event_constants.h`
+
+```c++
 extern const char kPasswordInfobarIgnored[];  // "password_infobar_ignored"
 extern const char kPasswordInfobarAccepted[];  // "password_infobar_accepted"
 ```
diff --git a/components/media_router/browser/issue_manager_unittest.cc b/components/media_router/browser/issue_manager_unittest.cc
index 03d198d..1b6d0712 100644
--- a/components/media_router/browser/issue_manager_unittest.cc
+++ b/components/media_router/browser/issue_manager_unittest.cc
@@ -17,9 +17,8 @@
 namespace {
 
 IssueInfo CreateTestIssue(IssueInfo::Severity severity) {
-  IssueInfo issue("title", IssueInfo::Action::DISMISS, severity);
+  IssueInfo issue("title", severity);
   issue.message = "message";
-  issue.help_page_id = 12345;
   return issue;
 }
 
diff --git a/components/media_router/common/issue.cc b/components/media_router/common/issue.cc
index 16f6b87..c6913db 100644
--- a/components/media_router/common/issue.cc
+++ b/components/media_router/common/issue.cc
@@ -13,35 +13,28 @@
 base::AtomicSequenceNumber g_next_issue_id;
 }  // namespace
 
-IssueInfo::IssueInfo()
-    : default_action(IssueInfo::Action::DISMISS),
-      severity(IssueInfo::Severity::NOTIFICATION),
-      help_page_id(IssueInfo::kUnknownHelpPageId) {}
-
-IssueInfo::IssueInfo(const std::string& title,
-                     const Action default_action,
-                     Severity severity)
-    : title(title),
-      default_action(default_action),
-      severity(severity),
-      help_page_id(IssueInfo::kUnknownHelpPageId) {}
-
-IssueInfo::IssueInfo(const IssueInfo& other) = default;
-
+IssueInfo::IssueInfo() = default;
+IssueInfo::IssueInfo(const IssueInfo&) = default;
+IssueInfo& IssueInfo::operator=(const IssueInfo&) = default;
+IssueInfo::IssueInfo(IssueInfo&&) = default;
+IssueInfo& IssueInfo::operator=(IssueInfo&&) = default;
 IssueInfo::~IssueInfo() = default;
 
-IssueInfo& IssueInfo::operator=(const IssueInfo& other) = default;
+IssueInfo::IssueInfo(const std::string& title, Severity severity)
+    : title(title), severity(severity) {}
 
 bool IssueInfo::operator==(const IssueInfo& other) const {
-  return title == other.title && default_action == other.default_action &&
-         severity == other.severity && message == other.message &&
-         secondary_actions == other.secondary_actions &&
-         route_id == other.route_id && help_page_id == other.help_page_id;
+  return title == other.title && severity == other.severity &&
+         message == other.message && route_id == other.route_id;
 }
 
-Issue::Issue(const IssueInfo& info)
-    : id_(g_next_issue_id.GetNext()), info_(info) {}
+Issue::Issue(IssueInfo info)
+    : id_(g_next_issue_id.GetNext()), info_(std::move(info)) {}
 
+Issue::Issue(const Issue&) = default;
+Issue& Issue::operator=(const Issue&) = default;
+Issue::Issue(Issue&&) = default;
+Issue& Issue::operator=(Issue&&) = default;
 Issue::~Issue() = default;
 
 }  // namespace media_router
diff --git a/components/media_router/common/issue.h b/components/media_router/common/issue.h
index ad58b0c..76062b67 100644
--- a/components/media_router/common/issue.h
+++ b/components/media_router/common/issue.h
@@ -6,7 +6,6 @@
 #define COMPONENTS_MEDIA_ROUTER_COMMON_ISSUE_H_
 
 #include <string>
-#include <vector>
 
 #include "components/media_router/common/media_route.h"
 #include "components/media_router/common/media_sink.h"
@@ -16,50 +15,30 @@
 // Contains the information relevant to an issue.
 struct IssueInfo {
  public:
-  // TODO(crbug.com/1366822): Secondary actions are no longer used and can be
-  // removed.
-  // Possible actions for an issue.
-  enum class Action {
-    DISMISS,
-    // NOTE: If LEARN_MORE is set as a possible action for an issue, then its
-    // |help_page_id_| must also be set to a valid value.
-    LEARN_MORE,
-
-    // Denotes enum value boundary. New values should be added above.
-    NUM_VALUES = LEARN_MORE
-  };
-
   // Severity type of an issue.
   enum class Severity { WARNING, NOTIFICATION };
 
-  static const int kUnknownHelpPageId = 0;
-
   // Used by Mojo and testing only.
   IssueInfo();
 
   // |title|: The title for the issue.
-  // |default_action|: Default action user can take to resolve the issue.
   // |severity|: The severity of the issue.
-  IssueInfo(const std::string& title, Action default_action, Severity severity);
-  IssueInfo(const IssueInfo& other);
+  IssueInfo(const std::string& title, Severity severity);
+  IssueInfo(const IssueInfo&);
+  IssueInfo& operator=(const IssueInfo&);
+  IssueInfo(IssueInfo&&);
+  IssueInfo& operator=(IssueInfo&&);
   ~IssueInfo();
 
-  IssueInfo& operator=(const IssueInfo& other);
   bool operator==(const IssueInfo& other) const;
 
   // Fields set with values provided to the constructor.
   std::string title;
-  Action default_action;
-  Severity severity;
+  Severity severity{IssueInfo::Severity::NOTIFICATION};
 
   // Description message for the issue.
   std::string message;
 
-  // Options the user can take to resolve the issue in addition to the
-  // default action. Can be empty. If non-empty, currently only one secondary
-  // action is supported.
-  std::vector<Action> secondary_actions;
-
   // ID of route associated with the Issue, or empty if no route is associated
   // with it.
   MediaRoute::Id route_id;
@@ -67,10 +46,6 @@
   // ID of the sink associated with this issue, or empty if no sink is
   // associated with it.
   MediaSink::Id sink_id;
-
-  // ID of help page to link to, if one of the actions is LEARN_MORE.
-  // Defaults to |kUnknownHelpPageId|.
-  int help_page_id;
 };
 
 // An issue that is associated with a globally unique ID. Created by
@@ -79,9 +54,11 @@
  public:
   using Id = int;
   // ID is generated during construction.
-  explicit Issue(const IssueInfo& info);
-  Issue(const Issue& other) = default;
-  Issue& operator=(const Issue& other) = default;
+  explicit Issue(IssueInfo info);
+  Issue(const Issue&);
+  Issue& operator=(const Issue&);
+  Issue(Issue&&);
+  Issue& operator=(Issue&&);
   ~Issue();
 
   const Id& id() const { return id_; }
diff --git a/components/media_router/common/issue_unittest.cc b/components/media_router/common/issue_unittest.cc
index 3457d82..58f60d4 100644
--- a/components/media_router/common/issue_unittest.cc
+++ b/components/media_router/common/issue_unittest.cc
@@ -10,103 +10,46 @@
 
 namespace {
 
-IssueInfo CreateWarningIssueInfo(IssueInfo::Action action_type) {
-  IssueInfo issue("title", action_type, IssueInfo::Severity::WARNING);
+IssueInfo CreateWarningIssueInfo() {
+  IssueInfo issue("title", IssueInfo::Severity::WARNING);
   issue.message = "message";
-  issue.help_page_id = 12345;
   return issue;
 }
 
-IssueInfo CreateNotificationRouteIssueInfoWithMessage(
-    IssueInfo::Action action_type) {
-  IssueInfo issue("title", action_type, IssueInfo::Severity::NOTIFICATION);
+IssueInfo CreateNotificationRouteIssueInfoWithMessage() {
+  IssueInfo issue("title", IssueInfo::Severity::NOTIFICATION);
   issue.message = "message";
-  issue.help_page_id = 12345;
   issue.route_id = "routeid";
   return issue;
 }
 
-IssueInfo CreateNotificationRouteIssueInfo(IssueInfo::Action action_type) {
-  IssueInfo issue("title", action_type, IssueInfo::Severity::NOTIFICATION);
-  issue.help_page_id = 12345;
+IssueInfo CreateNotificationRouteIssueInfo() {
+  IssueInfo issue("title", IssueInfo::Severity::NOTIFICATION);
   issue.route_id = "routeid";
   return issue;
 }
 
 }  // namespace
 
-// Tests Issues without any secondary actions.
-TEST(IssueInfoUnitTest, CustomIssueConstructionWithNoSecondaryActions) {
-  IssueInfo issue1 = CreateWarningIssueInfo(IssueInfo::Action::DISMISS);
+TEST(IssueInfoUnitTest, CreateIssueInfo) {
+  IssueInfo issue1 = CreateWarningIssueInfo();
 
   EXPECT_EQ("title", issue1.title);
   EXPECT_EQ("message", issue1.message);
-  EXPECT_EQ(IssueInfo::Action::DISMISS, issue1.default_action);
-  EXPECT_TRUE(issue1.secondary_actions.empty());
-  EXPECT_EQ(IssueInfo::Severity::WARNING, issue1.severity);
-  EXPECT_EQ("", issue1.route_id);
-  EXPECT_EQ(12345, issue1.help_page_id);
-
-  IssueInfo issue2 =
-      CreateNotificationRouteIssueInfoWithMessage(IssueInfo::Action::DISMISS);
-
-  EXPECT_EQ("title", issue2.title);
-  EXPECT_EQ("message", issue2.message);
-  EXPECT_EQ(IssueInfo::Action::DISMISS, issue1.default_action);
-  EXPECT_TRUE(issue2.secondary_actions.empty());
-  EXPECT_EQ(IssueInfo::Severity::NOTIFICATION, issue2.severity);
-  EXPECT_EQ("routeid", issue2.route_id);
-  EXPECT_EQ(12345, issue2.help_page_id);
-
-  IssueInfo issue3 =
-      CreateNotificationRouteIssueInfo(IssueInfo::Action::DISMISS);
-
-  EXPECT_EQ("title", issue3.title);
-  EXPECT_EQ("", issue3.message);
-  EXPECT_EQ(IssueInfo::Action::DISMISS, issue1.default_action);
-  EXPECT_TRUE(issue3.secondary_actions.empty());
-  EXPECT_EQ(IssueInfo::Severity::NOTIFICATION, issue3.severity);
-  EXPECT_EQ("routeid", issue3.route_id);
-  EXPECT_EQ(12345, issue3.help_page_id);
-}
-
-// Tests Issues with secondary actions.
-TEST(IssueInfoUnitTest, CustomIssueConstructionWithSecondaryActions) {
-  std::vector<IssueInfo::Action> secondary_actions;
-  secondary_actions.push_back(IssueInfo::Action::DISMISS);
-
-  IssueInfo issue1 = CreateWarningIssueInfo(IssueInfo::Action::LEARN_MORE);
-  issue1.secondary_actions = secondary_actions;
-
-  EXPECT_EQ("title", issue1.title);
-  EXPECT_EQ("message", issue1.message);
-  EXPECT_EQ(IssueInfo::Action::LEARN_MORE, issue1.default_action);
-  EXPECT_FALSE(issue1.secondary_actions.empty());
-  EXPECT_EQ(1u, issue1.secondary_actions.size());
   EXPECT_EQ(IssueInfo::Severity::WARNING, issue1.severity);
   EXPECT_EQ("", issue1.route_id);
 
-  IssueInfo issue2 = CreateNotificationRouteIssueInfoWithMessage(
-      IssueInfo::Action::LEARN_MORE);
-  issue2.secondary_actions = secondary_actions;
+  IssueInfo issue2 = CreateNotificationRouteIssueInfoWithMessage();
 
   EXPECT_EQ("title", issue2.title);
   EXPECT_EQ("message", issue2.message);
-  EXPECT_EQ(IssueInfo::Action::LEARN_MORE, issue2.default_action);
-  EXPECT_FALSE(issue2.secondary_actions.empty());
-  EXPECT_EQ(1u, issue2.secondary_actions.size());
   EXPECT_EQ(IssueInfo::Severity::NOTIFICATION, issue2.severity);
   EXPECT_EQ("routeid", issue2.route_id);
 
-  IssueInfo issue3 =
-      CreateNotificationRouteIssueInfo(IssueInfo::Action::LEARN_MORE);
-  issue3.secondary_actions = secondary_actions;
+  IssueInfo issue3 = CreateNotificationRouteIssueInfo();
 
   EXPECT_EQ("title", issue3.title);
   EXPECT_EQ("", issue3.message);
-  EXPECT_EQ(IssueInfo::Action::LEARN_MORE, issue3.default_action);
-  EXPECT_FALSE(issue3.secondary_actions.empty());
-  EXPECT_EQ(1u, issue3.secondary_actions.size());
   EXPECT_EQ(IssueInfo::Severity::NOTIFICATION, issue3.severity);
   EXPECT_EQ("routeid", issue3.route_id);
 }
diff --git a/components/media_router/common/mojom/media_router.mojom b/components/media_router/common/mojom/media_router.mojom
index f02f8a9..995ba23 100644
--- a/components/media_router/common/mojom/media_router.mojom
+++ b/components/media_router/common/mojom/media_router.mojom
@@ -134,11 +134,6 @@
     NOTIFICATION
   };
 
-  enum ActionType {
-    DISMISS,
-    LEARN_MORE
-  };
-
   // If set, the ID of the route to which this issue pertains.
   // If this is an empty string (default), then this is a global issue.
   string route_id;
@@ -156,13 +151,6 @@
   // Message about issue detail or how to handle issue.
   // Messages should be suitable for end users to decide which actions to take.
   string? message;
-
-  ActionType default_action;
-
-  array<ActionType> secondary_actions;
-
-  // The ID of the help page to be opened if users select learn_more.
-  int32 help_page_id;
 };
 
 struct RouteMessage {
diff --git a/components/media_router/common/mojom/media_router_mojom_traits.cc b/components/media_router/common/mojom/media_router_mojom_traits.cc
index 6b3284f..9e7bbe9 100644
--- a/components/media_router/common/mojom/media_router_mojom_traits.cc
+++ b/components/media_router/common/mojom/media_router_mojom_traits.cc
@@ -19,9 +19,6 @@
   if (!data.ReadTitle(&out->title))
     return false;
 
-  if (!data.ReadDefaultAction(&out->default_action))
-    return false;
-
   if (!data.ReadSeverity(&out->severity))
     return false;
 
@@ -31,17 +28,12 @@
 
   out->message = message.value_or(std::string());
 
-  if (!data.ReadSecondaryActions(&out->secondary_actions))
-    return false;
-
   if (!data.ReadRouteId(&out->route_id))
     return false;
 
   if (!data.ReadSinkId(&out->sink_id))
     return false;
 
-  out->help_page_id = data.help_page_id();
-
   return true;
 }
 
diff --git a/components/media_router/common/mojom/media_router_mojom_traits.h b/components/media_router/common/mojom/media_router_mojom_traits.h
index 81f4afd..ced5f4d7 100644
--- a/components/media_router/common/mojom/media_router_mojom_traits.h
+++ b/components/media_router/common/mojom/media_router_mojom_traits.h
@@ -20,35 +20,6 @@
 // Issue
 
 template <>
-struct EnumTraits<media_router::mojom::Issue_ActionType,
-                  media_router::IssueInfo::Action> {
-  static media_router::mojom::Issue_ActionType ToMojom(
-      media_router::IssueInfo::Action action) {
-    switch (action) {
-      case media_router::IssueInfo::Action::DISMISS:
-        return media_router::mojom::Issue_ActionType::DISMISS;
-      case media_router::IssueInfo::Action::LEARN_MORE:
-        return media_router::mojom::Issue_ActionType::LEARN_MORE;
-    }
-    NOTREACHED() << "Unknown issue action type " << static_cast<int>(action);
-    return media_router::mojom::Issue_ActionType::DISMISS;
-  }
-
-  static bool FromMojom(media_router::mojom::Issue_ActionType input,
-                        media_router::IssueInfo::Action* output) {
-    switch (input) {
-      case media_router::mojom::Issue_ActionType::DISMISS:
-        *output = media_router::IssueInfo::Action::DISMISS;
-        return true;
-      case media_router::mojom::Issue_ActionType::LEARN_MORE:
-        *output = media_router::IssueInfo::Action::LEARN_MORE;
-        return true;
-    }
-    return false;
-  }
-};
-
-template <>
 struct EnumTraits<media_router::mojom::Issue_Severity,
                   media_router::IssueInfo::Severity> {
   static media_router::mojom::Issue_Severity ToMojom(
@@ -178,20 +149,6 @@
   static const std::string& message(const media_router::IssueInfo& issue) {
     return issue.message;
   }
-
-  static media_router::IssueInfo::Action default_action(
-      const media_router::IssueInfo& issue) {
-    return issue.default_action;
-  }
-
-  static const std::vector<media_router::IssueInfo::Action>& secondary_actions(
-      const media_router::IssueInfo& issue) {
-    return issue.secondary_actions;
-  }
-
-  static int32_t help_page_id(const media_router::IssueInfo& issue) {
-    return issue.help_page_id;
-  }
 };
 
 // MediaSink
diff --git a/components/omnibox/browser/autocomplete_grouper_sections.h b/components/omnibox/browser/autocomplete_grouper_sections.h
index b0b865a..9f5dca11 100644
--- a/components/omnibox/browser/autocomplete_grouper_sections.h
+++ b/components/omnibox/browser/autocomplete_grouper_sections.h
@@ -8,9 +8,9 @@
 #include <memory>
 #include <vector>
 
+#include "components/omnibox/browser/autocomplete_grouper_groups.h"
 #include "components/omnibox/browser/autocomplete_match.h"
 
-class Group;
 class Section;
 using PGroups = std::vector<std::unique_ptr<Group>>;
 using PSections = std::vector<std::unique_ptr<Section>>;
diff --git a/components/password_manager/core/browser/login_database_ios.cc b/components/password_manager/core/browser/login_database_ios.cc
index 769f318fd..c53ca25 100644
--- a/components/password_manager/core/browser/login_database_ios.cc
+++ b/components/password_manager/core/browser/login_database_ios.cc
@@ -61,7 +61,10 @@
 
   OSStatus status = SecItemAdd(attributes, NULL);
   if (status != errSecSuccess) {
-    NOTREACHED() << "Unable to save password in keychain: " << status;
+    // TODO(crbug.com/1091121): This was a NOTREACHED() that would trigger when
+    // sync runs on a locked device. When the linked bug is resolved it may be
+    // possible to turn the LOG(ERROR) back into a NOTREACHED().
+    LOG(ERROR) << "Unable to save password in keychain: " << status;
     if (status == errSecDuplicateItem || status == errSecDecode)
       return ENCRYPTION_RESULT_ITEM_FAILURE;
     else
diff --git a/components/payments/content/payment_request.cc b/components/payments/content/payment_request.cc
index c13eba8..09b39c9 100644
--- a/components/payments/content/payment_request.cc
+++ b/components/payments/content/payment_request.cc
@@ -901,6 +901,10 @@
 }
 
 void PaymentRequest::Pay() {
+  if (observer_for_testing_) {
+    observer_for_testing_->OnPayCalled();
+  }
+
   journey_logger_.SetPayClicked();
   journey_logger_.RecordCheckoutStep(
       JourneyLogger::CheckoutFunnelStep::kPaymentHandlerInvoked);
diff --git a/components/payments/content/payment_request.h b/components/payments/content/payment_request.h
index bed9b43..6cc50dc 100644
--- a/components/payments/content/payment_request.h
+++ b/components/payments/content/payment_request.h
@@ -73,6 +73,7 @@
     virtual void OnErrorDisplayed() {}
     virtual void OnNotSupportedError() = 0;
     virtual void OnConnectionTerminated() = 0;
+    virtual void OnPayCalled() = 0;
     virtual void OnAbortCalled() = 0;
     virtual void OnCompleteCalled() {}
 
diff --git a/components/policy/resources/templates/policy_definitions/BrowserIdle/IdleTimeout.yaml b/components/policy/resources/templates/policy_definitions/BrowserIdle/IdleTimeout.yaml
index 98f0bdf..a5a580b 100644
--- a/components/policy/resources/templates/policy_definitions/BrowserIdle/IdleTimeout.yaml
+++ b/components/policy/resources/templates/policy_definitions/BrowserIdle/IdleTimeout.yaml
@@ -16,6 +16,7 @@
   per_profile: true
 future_on:
 - chrome.*
+- android
 owners:
 - nicolaso@chromium.org
 - cbe-magic@google.com
diff --git a/components/policy/resources/templates/policy_definitions/BrowserIdle/IdleTimeoutActions.yaml b/components/policy/resources/templates/policy_definitions/BrowserIdle/IdleTimeoutActions.yaml
index b71712ac..3416564 100644
--- a/components/policy/resources/templates/policy_definitions/BrowserIdle/IdleTimeoutActions.yaml
+++ b/components/policy/resources/templates/policy_definitions/BrowserIdle/IdleTimeoutActions.yaml
@@ -10,9 +10,9 @@
 
         Supported actions are:
 
-        '<ph name="CLOSE_BROWSERS_ACTION">close_browsers</ph>': close all browser windows and PWAs for this profile.
+        '<ph name="CLOSE_BROWSERS_ACTION">close_browsers</ph>': close all browser windows and PWAs for this profile. Not supported on Android.
 
-        '<ph name="SHOW_PROFILE_PICKER_ACTION">show_profile_picker</ph>': show the Profile Picker window.
+        '<ph name="SHOW_PROFILE_PICKER_ACTION">show_profile_picker</ph>': show the Profile Picker window. Not supported on Android.
 
         '<ph name="CLEAR_BROWSING_HISTORY_ACTION">clear_browsing_history</ph>', '<ph name="CLEAR_DOWNLOAD_HISTORY_ACTION">clear_download_history</ph>', '<ph name="CLEAR_COOKIES_AND_OTHER_SITE_DATA_ACTION">clear_cookies_and_other_site_data</ph>', '<ph name="CLEAR_CACHED_IMAGES_AND_FILES_ACTION">clear_cached_images_and_files</ph>', '<ph name="CLEAR_PASSWORD_SIGNIN_ACTION">clear_password_signing</ph>', '<ph name="CLEAR_AUTOFILL_ACTION">clear_autofill</ph>' , '<ph name="CLEAR_SITE_SETTINGS_ACTION">clear_site_settings</ph>' , '<ph name="CLEAR_HOSTED_APP_DATA_ACTION">clear_hosted_app_data</ph>': clear the corresponding browsing data. See the <ph name="CLEAR_BROWSING_DATA_ON_EXIT_LIST_POLICY_NAME">ClearBrowsingDataOnExitList</ph> policy for more details.
 example_value:
@@ -23,6 +23,7 @@
   per_profile: true
 future_on:
 - chrome.*
+- android
 owners:
 - nicolaso@chromium.org
 - cbe-magic@google.com
diff --git a/components/policy/resources/templates/policy_definitions/Miscellaneous/GetDisplayMediaSetSelectAllScreensAllowedForUrls.yaml b/components/policy/resources/templates/policy_definitions/Miscellaneous/GetDisplayMediaSetSelectAllScreensAllowedForUrls.yaml
index f1ed2ad..ece685c 100644
--- a/components/policy/resources/templates/policy_definitions/Miscellaneous/GetDisplayMediaSetSelectAllScreensAllowedForUrls.yaml
+++ b/components/policy/resources/templates/policy_definitions/Miscellaneous/GetDisplayMediaSetSelectAllScreensAllowedForUrls.yaml
@@ -19,5 +19,6 @@
   type: array
 supported_on:
 - chrome_os:102-
+- chrome.linux:111-
 tags: []
 type: list
diff --git a/components/privacy_sandbox/BUILD.gn b/components/privacy_sandbox/BUILD.gn
index 9079e71..d9045ce 100644
--- a/components/privacy_sandbox/BUILD.gn
+++ b/components/privacy_sandbox/BUILD.gn
@@ -33,8 +33,9 @@
   sources = [
     "canonical_topic.cc",
     "canonical_topic.h",
-    "privacy_sandbox_settings.cc",
     "privacy_sandbox_settings.h",
+    "privacy_sandbox_settings_impl.cc",
+    "privacy_sandbox_settings_impl.h",
   ]
 
   deps = [
@@ -62,7 +63,7 @@
   testonly = true
   sources = [
     "canonical_topic_unittest.cc",
-    "privacy_sandbox_settings_unittest.cc",
+    "privacy_sandbox_settings_impl_unittest.cc",
   ]
 
   deps = [
@@ -85,6 +86,8 @@
 source_set("test_support") {
   testonly = true
   sources = [
+    "mock_privacy_sandbox_settings.cc",
+    "mock_privacy_sandbox_settings.h",
     "privacy_sandbox_test_util.cc",
     "privacy_sandbox_test_util.h",
   ]
diff --git a/components/privacy_sandbox/mock_privacy_sandbox_settings.cc b/components/privacy_sandbox/mock_privacy_sandbox_settings.cc
new file mode 100644
index 0000000..b497da3
--- /dev/null
+++ b/components/privacy_sandbox/mock_privacy_sandbox_settings.cc
@@ -0,0 +1,18 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/privacy_sandbox/mock_privacy_sandbox_settings.h"
+
+namespace privacy_sandbox_test_util {
+
+MockPrivacySandboxSettings::MockPrivacySandboxSettings() = default;
+MockPrivacySandboxSettings::~MockPrivacySandboxSettings() = default;
+
+void MockPrivacySandboxSettings::SetUpDefaultResponse() {
+  ON_CALL(*this, IsPrivacySandboxRestricted).WillByDefault([]() {
+    return false;
+  });
+}
+
+}  // namespace privacy_sandbox_test_util
diff --git a/components/privacy_sandbox/mock_privacy_sandbox_settings.h b/components/privacy_sandbox/mock_privacy_sandbox_settings.h
new file mode 100644
index 0000000..643f1577
--- /dev/null
+++ b/components/privacy_sandbox/mock_privacy_sandbox_settings.h
@@ -0,0 +1,89 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PRIVACY_SANDBOX_MOCK_PRIVACY_SANDBOX_SETTINGS_H_
+#define COMPONENTS_PRIVACY_SANDBOX_MOCK_PRIVACY_SANDBOX_SETTINGS_H_
+
+#include "components/privacy_sandbox/privacy_sandbox_settings.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace privacy_sandbox_test_util {
+
+class MockPrivacySandboxSettings
+    : public privacy_sandbox::PrivacySandboxSettings {
+ public:
+  MockPrivacySandboxSettings();
+  ~MockPrivacySandboxSettings() override;
+  void SetUpDefaultResponse();
+
+  // PrivacySandboxSettings:
+  MOCK_METHOD(bool, IsTopicsAllowed, (), (override, const));
+  MOCK_METHOD(bool,
+              IsTopicsAllowedForContext,
+              (const url::Origin&, const GURL&),
+              (override, const));
+  MOCK_METHOD(bool,
+              IsTopicAllowed,
+              (const privacy_sandbox::CanonicalTopic&),
+              (override));
+  MOCK_METHOD(void,
+              SetTopicAllowed,
+              (const privacy_sandbox::CanonicalTopic&, bool),
+              (override));
+  MOCK_METHOD(void, ClearTopicSettings, (base::Time, base::Time), (override));
+  MOCK_METHOD(base::Time, TopicsDataAccessibleSince, (), (override, const));
+  MOCK_METHOD(bool,
+              IsAttributionReportingAllowed,
+              (const url::Origin&, const url::Origin&),
+              (override, const));
+  MOCK_METHOD(bool,
+              MaySendAttributionReport,
+              (const url::Origin&, const url::Origin&, const url::Origin&),
+              (override, const));
+  MOCK_METHOD(void,
+              SetFledgeJoiningAllowed,
+              (const std::string&, bool),
+              (override));
+  MOCK_METHOD(void,
+              ClearFledgeJoiningAllowedSettings,
+              (base::Time, base::Time),
+              (override));
+  MOCK_METHOD(bool,
+              IsFledgeJoiningAllowed,
+              (const url::Origin&),
+              (override, const));
+  MOCK_METHOD(bool,
+              IsFledgeAllowed,
+              (const url::Origin&, const url::Origin&),
+              (override, const));
+  MOCK_METHOD(bool,
+              IsSharedStorageAllowed,
+              (const url::Origin&, const url::Origin&),
+              (override, const));
+  MOCK_METHOD(bool,
+              IsSharedStorageSelectURLAllowed,
+              (const url::Origin&, const url::Origin&),
+              (override, const));
+  MOCK_METHOD(bool,
+              IsPrivateAggregationAllowed,
+              (const url::Origin&, const url::Origin&),
+              (override, const));
+  MOCK_METHOD(bool, IsPrivacySandboxEnabled, (), (override, const));
+  MOCK_METHOD(void, SetAllPrivacySandboxAllowedForTesting, (), (override));
+  MOCK_METHOD(void, SetTopicsBlockedForTesting, (), (override));
+  MOCK_METHOD(void, SetPrivacySandboxEnabled, (bool), (override));
+  MOCK_METHOD(bool, IsTrustTokensAllowed, (), (override));
+  MOCK_METHOD(bool, IsPrivacySandboxRestricted, (), (override, const));
+  MOCK_METHOD(void, OnCookiesCleared, (), (override));
+  MOCK_METHOD(void, AddObserver, (Observer*), (override));
+  MOCK_METHOD(void, RemoveObserver, (Observer*), (override));
+  MOCK_METHOD(void,
+              SetDelegateForTesting,
+              (std::unique_ptr<Delegate>),
+              (override));
+};
+
+}  // namespace privacy_sandbox_test_util
+
+#endif  // COMPONENTS_PRIVACY_SANDBOX_PRIVACY_SANDBOX_TEST_UTIL_H_
diff --git a/components/privacy_sandbox/privacy_sandbox_settings.h b/components/privacy_sandbox/privacy_sandbox_settings.h
index e80c508..441a11d 100644
--- a/components/privacy_sandbox/privacy_sandbox_settings.h
+++ b/components/privacy_sandbox/privacy_sandbox_settings.h
@@ -5,23 +5,11 @@
 #ifndef COMPONENTS_PRIVACY_SANDBOX_PRIVACY_SANDBOX_SETTINGS_H_
 #define COMPONENTS_PRIVACY_SANDBOX_PRIVACY_SANDBOX_SETTINGS_H_
 
-#include "base/gtest_prod_util.h"
-#include "base/memory/raw_ptr.h"
-#include "base/observer_list.h"
-#include "base/time/time.h"
 #include "components/keyed_service/core/keyed_service.h"
-#include "components/prefs/pref_change_registrar.h"
 #include "components/privacy_sandbox/canonical_topic.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
-class HostContentSettingsMap;
-class PrefService;
 class GURL;
 
-namespace content_settings {
-class CookieSettings;
-}
-
 namespace url {
 class Origin;
 }
@@ -69,59 +57,55 @@
     virtual bool IsIncognitoProfile() const = 0;
   };
 
-  PrivacySandboxSettings(
-      std::unique_ptr<Delegate> delegate,
-      HostContentSettingsMap* host_content_settings_map,
-      scoped_refptr<content_settings::CookieSettings> cookie_settings,
-      PrefService* pref_service);
-  ~PrivacySandboxSettings() override;
-
   // Returns whether the Topics API is allowed at all. If false, Topics API
   // calculations should not occur. If true, the more specific function,
   // IsTopicsApiAllowedForContext(), should be consulted for the relevant
   // context.
-  bool IsTopicsAllowed() const;
+  virtual bool IsTopicsAllowed() const = 0;
 
   // Determines whether the Topics API is allowable in a particular context.
   // |top_frame_origin| is used to check for content settings which could both
   // affect 1P and 3P contexts.
-  bool IsTopicsAllowedForContext(const url::Origin& top_frame_origin,
-                                 const GURL& url) const;
+  virtual bool IsTopicsAllowedForContext(const url::Origin& top_frame_origin,
+                                         const GURL& url) const = 0;
 
   // Returns whether |topic| can be either considered as a top topic for the
   // current epoch, or provided to a website as a previous / current epochs
   // site assigned topic.
-  bool IsTopicAllowed(const CanonicalTopic& topic);
+  virtual bool IsTopicAllowed(const CanonicalTopic& topic) = 0;
 
   // Sets |topic| to |allowed|. Whether a topic is allowed or not is made
   // available through IsTopicAllowed().
-  void SetTopicAllowed(const CanonicalTopic& topic, bool allowed);
+  virtual void SetTopicAllowed(const CanonicalTopic& topic, bool allowed) = 0;
 
   // Removes all Topic settings with creation times between |start_time|
   // and |end_time|. This allows for integration with the existing browsing data
   // remover, such as the one powering Clear Browser Data.
-  void ClearTopicSettings(base::Time start_time, base::Time end_time);
+  virtual void ClearTopicSettings(base::Time start_time,
+                                  base::Time end_time) = 0;
 
   // Returns the point in time from which history is eligible to be used when
   // calculating a user's Topics API topics. Reset when a user clears all
   // cookies, or when the browser restarts with "Clear on exit" enabled. The
   // returned time will have been fuzzed for local privacy, and so may be in the
   // future, in which case no history is eligible.
-  base::Time TopicsDataAccessibleSince() const;
+  virtual base::Time TopicsDataAccessibleSince() const = 0;
 
   // Determines whether Attribution Reporting is allowable in a particular
   // context. Should be called at both source and trigger registration. At each
   // of these points |top_frame_origin| is the same as either the source origin
   // or the destination origin respectively.
-  bool IsAttributionReportingAllowed(const url::Origin& top_frame_origin,
-                                     const url::Origin& reporting_origin) const;
+  virtual bool IsAttributionReportingAllowed(
+      const url::Origin& top_frame_origin,
+      const url::Origin& reporting_origin) const = 0;
 
   // Called before sending the associated attribution report to
   // |reporting_origin|. Re-checks that |reporting_origin| is allowable as a 3P
   // on both |source_origin| and |destination_origin|.
-  bool MaySendAttributionReport(const url::Origin& source_origin,
-                                const url::Origin& destination_origin,
-                                const url::Origin& reporting_origin) const;
+  virtual bool MaySendAttributionReport(
+      const url::Origin& source_origin,
+      const url::Origin& destination_origin,
+      const url::Origin& reporting_origin) const = 0;
 
   // Sets the ability for |top_frame_etld_plus1| to join the profile to interest
   // groups to |allowed|. This information is stored in preferences, and is made
@@ -129,29 +113,31 @@
   // should in most circumstances be a valid eTLD+1, but hosts are accepted to
   // allow for shifts in private registries. Entries are converted into wildcard
   // subdomain ContentSettingsPattern before comparison.
-  void SetFledgeJoiningAllowed(const std::string& top_frame_etld_plus1,
-                               bool allowed);
+  virtual void SetFledgeJoiningAllowed(const std::string& top_frame_etld_plus1,
+                                       bool allowed) = 0;
 
   // Clears any FLEDGE joining block settings with creation times between
   // |start_time| and |end_time|.
-  void ClearFledgeJoiningAllowedSettings(base::Time start_time,
-                                         base::Time end_time);
+  virtual void ClearFledgeJoiningAllowedSettings(base::Time start_time,
+                                                 base::Time end_time) = 0;
 
   // Determines whether the user may be joined to FLEDGE interest groups on, or
   // by, |top_frame_origin|. This is an additional check that must be
   // combined with the more generic IsFledgeAllowed().
-  bool IsFledgeJoiningAllowed(const url::Origin& top_frame_origin) const;
+  virtual bool IsFledgeJoiningAllowed(
+      const url::Origin& top_frame_origin) const = 0;
 
   // Determine whether |auction_party| can register an interest group, or sell
   // buy in an auction, on |top_frame_origin|.
-  bool IsFledgeAllowed(const url::Origin& top_frame_origin,
-                       const url::Origin& auction_party) const;
+  virtual bool IsFledgeAllowed(const url::Origin& top_frame_origin,
+                               const url::Origin& auction_party) const = 0;
 
   // Determines whether Shared Storage is allowable in a particular context.
   // `top_frame_origin` can be the same as `accessing_origin` in the case of a
   // top-level document calling Shared Storage.
-  bool IsSharedStorageAllowed(const url::Origin& top_frame_origin,
-                              const url::Origin& accessing_origin) const;
+  virtual bool IsSharedStorageAllowed(
+      const url::Origin& top_frame_origin,
+      const url::Origin& accessing_origin) const = 0;
 
   // Controls whether Shared Storage SelectURL is allowable for
   // `accessing_origin` in the context of `top_frame_origin`. Does not override
@@ -159,31 +145,32 @@
   // TODO(crbug.com/1378703): This just redirects to the general
   // IsSharedStorageAllowed(). The implementation needs to be updated to reflect
   // the M1 preferences when release 4 is enabled.
-  bool IsSharedStorageSelectURLAllowed(
+  virtual bool IsSharedStorageSelectURLAllowed(
       const url::Origin& top_frame_origin,
-      const url::Origin& accessing_origin) const;
+      const url::Origin& accessing_origin) const = 0;
 
   // Determines whether the Private Aggregation API is allowable in a particular
   // context. `top_frame_origin` is the associated top-frame origin of the
   // calling context. Applicable to all uses of Private Aggregation.
-  bool IsPrivateAggregationAllowed(const url::Origin& top_frame_origin,
-                                   const url::Origin& reporting_origin) const;
+  virtual bool IsPrivateAggregationAllowed(
+      const url::Origin& top_frame_origin,
+      const url::Origin& reporting_origin) const = 0;
 
   // Returns whether the profile has the Privacy Sandbox enabled. This consults
   // the main preference, as well as the delegate to check whether the sandbox
   // is restricted. It does not consider any cookie settings. A return value of
   // false means that no Privacy Sandbox operations can occur. A return value of
   // true must be followed up with the appropriate IsXAllowed() call.
-  bool IsPrivacySandboxEnabled() const;
+  virtual bool IsPrivacySandboxEnabled() const = 0;
 
   // Allows all Privacy Sandbox prefs for testing. This should be used if tests
   // don't depend on specific access control and just would like to have Privacy
   // Sandbox allowed. Doesn't affect other non-default settings which might
   // disallow APIs e.g. site data exceptions.
-  void SetAllPrivacySandboxAllowedForTesting();
+  virtual void SetAllPrivacySandboxAllowedForTesting() = 0;
 
   // Blocks Topics pref for testing.
-  void SetTopicsBlockedForTesting();
+  virtual void SetTopicsBlockedForTesting() = 0;
 
   // Disables the Privacy Sandbox completely if |enabled| is false, if |enabled|
   // is true, more granular checks will still be performed, and the delegate
@@ -191,103 +178,28 @@
   // contexts.
   // DEPRECATED: Use `SetAllPrivacySandboxAllowedForTesting()` to allow all
   // Privacy Sandbox prefs or per-API block-for-testing functions.
-  void SetPrivacySandboxEnabled(bool enabled);
+  virtual void SetPrivacySandboxEnabled(bool enabled) = 0;
 
   // Returns whether Trust Tokens are "generally" available. A return value of
   // false is authoritative, while a value of true must be followed by the
   // appropriate context specific check.
-  bool IsTrustTokensAllowed();
+  virtual bool IsTrustTokensAllowed() = 0;
 
   // Returns whether the Privacy Sandbox is being restricted by the associated
   // delegate. Forwards directly to the corresponding delegate function.
   // Virtual to allow mocking in tests.
-  virtual bool IsPrivacySandboxRestricted() const;
+  virtual bool IsPrivacySandboxRestricted() const = 0;
 
   // Called when there's a broad cookies clearing action. For example, this
   // should be called on "Clear browsing data", but shouldn't be called on the
   // Clear-Site-Data header, as it's restricted to a specific site.
-  void OnCookiesCleared();
+  virtual void OnCookiesCleared() = 0;
 
-  // Called when the main privacy sandbox preference is changed.
-  void OnPrivacySandboxPrefChanged();
-
-  // Called when the First-Party Sets enabled preference is changed.
-  void OnFirstPartySetsEnabledPrefChanged();
-
-  void AddObserver(Observer* observer);
-  void RemoveObserver(Observer* observer);
+  virtual void AddObserver(Observer* observer) = 0;
+  virtual void RemoveObserver(Observer* observer) = 0;
 
   // Overrides the internal delegate for test purposes.
-  void SetDelegateForTesting(std::unique_ptr<Delegate> delegate);
-
- protected:
-  // Protected default constructor to allow mocking in tests.
-  PrivacySandboxSettings();
-
-  // Determines based on the current features, preferences and provided
-  // |cookie_settings| whether Privacy Sandbox APIs are generally allowable for
-  // |url| on |top_frame_origin|. Individual APIs may perform additional checks
-  // for allowability (such as incognito) ontop of this. |cookie_settings| is
-  // provided as a parameter to allow callers to cache it between calls.
-  bool IsPrivacySandboxEnabledForContext(
-      const absl::optional<url::Origin>& top_frame_origin,
-      const GURL& url) const;
-
-  void SetTopicsDataAccessibleFromNow() const;
-
- private:
-  friend class PrivacySandboxSettingsM1Test;
-
-  // These values are persisted to logs. Entries should not be renumbered and
-  // numeric values should never be reused.
-  enum class Status {
-    kAllowed,
-    kRestricted,
-    kIncognitoProfile,
-    kApisDisabled,
-    kSiteDataAccessBlocked,
-    kMaxValue = kSiteDataAccessBlocked,
-  };
-
-  static bool IsAllowed(Status status);
-
-  // Whether the site associated with the URL is allowed to access privacy
-  // sandbox APIs within the context of |top_frame_origin|.
-  Status GetSiteAccessAllowedStatus(const url::Origin& top_frame_origin,
-                                    const GURL& url) const;
-
-  // Whether the privacy sandbox APIs can be allowed given the current
-  // environment. For example, the privacy sandbox is always disabled in
-  // Incognito and for restricted accounts.
-  Status GetPrivacySandboxAllowedStatus() const;
-
-  // Whether the privacy sandbox associated with  the |pref_name| is enabled.
-  // For individual sites, check as well with GetSiteAccessAllowedStatus.
-  Status GetM1PrivacySandboxApiEnabledStatus(
-      const std::string& pref_name) const;
-
-  // Whether the Topics API can be allowed given the current
-  // environment or the reason why it is not allowed.
-  Status GetM1TopicAllowedStatus() const;
-
-  // Whether Attribution Reporting API can be allowed given the current
-  // environment or the reason why it is not allowed.
-  Status GetM1AttributionReportingAllowedStatus(
-      const url::Origin& top_frame_origin,
-      const url::Origin& reporting_origin) const;
-
-  // Whether Fledge can be allowed given the current environment or the reason
-  // why it is not allowed.
-  Status GetM1FledgeAllowedStatus(const url::Origin& top_frame_origin,
-                                  const url::Origin& accessing_origin) const;
-
-  base::ObserverList<Observer>::Unchecked observers_;
-
-  std::unique_ptr<Delegate> delegate_;
-  raw_ptr<HostContentSettingsMap, DanglingUntriaged> host_content_settings_map_;
-  scoped_refptr<content_settings::CookieSettings> cookie_settings_;
-  raw_ptr<PrefService, DanglingUntriaged> pref_service_;
-  PrefChangeRegistrar pref_change_registrar_;
+  virtual void SetDelegateForTesting(std::unique_ptr<Delegate> delegate) = 0;
 };
 
 }  // namespace privacy_sandbox
diff --git a/components/privacy_sandbox/privacy_sandbox_settings.cc b/components/privacy_sandbox/privacy_sandbox_settings_impl.cc
similarity index 85%
rename from components/privacy_sandbox/privacy_sandbox_settings.cc
rename to components/privacy_sandbox/privacy_sandbox_settings_impl.cc
index 882ac1c..a6b914aa 100644
--- a/components/privacy_sandbox/privacy_sandbox_settings.cc
+++ b/components/privacy_sandbox/privacy_sandbox_settings_impl.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 "components/privacy_sandbox/privacy_sandbox_settings.h"
+#include "components/privacy_sandbox/privacy_sandbox_settings_impl.h"
 #include <cstddef>
 
 #include "base/feature_list.h"
@@ -62,11 +62,11 @@
 }  // namespace
 
 // static
-bool PrivacySandboxSettings::IsAllowed(Status status) {
+bool PrivacySandboxSettingsImpl::IsAllowed(Status status) {
   return status == Status::kAllowed;
 }
 
-PrivacySandboxSettings::PrivacySandboxSettings(
+PrivacySandboxSettingsImpl::PrivacySandboxSettingsImpl(
     std::unique_ptr<Delegate> delegate,
     HostContentSettingsMap* host_content_settings_map,
     scoped_refptr<content_settings::CookieSettings> cookie_settings,
@@ -89,24 +89,25 @@
   pref_change_registrar_.Init(pref_service_);
   pref_change_registrar_.Add(
       prefs::kPrivacySandboxApisEnabledV2,
-      base::BindRepeating(&PrivacySandboxSettings::OnPrivacySandboxPrefChanged,
-                          base::Unretained(this)));
+      base::BindRepeating(
+          &PrivacySandboxSettingsImpl::OnPrivacySandboxPrefChanged,
+          base::Unretained(this)));
   pref_change_registrar_.Add(
       prefs::kPrivacySandboxFirstPartySetsEnabled,
       base::BindRepeating(
-          &PrivacySandboxSettings::OnFirstPartySetsEnabledPrefChanged,
+          &PrivacySandboxSettingsImpl::OnFirstPartySetsEnabledPrefChanged,
           base::Unretained(this)));
 }
 
-PrivacySandboxSettings::~PrivacySandboxSettings() = default;
+PrivacySandboxSettingsImpl::~PrivacySandboxSettingsImpl() = default;
 
-PrivacySandboxSettings::Status PrivacySandboxSettings::GetM1TopicAllowedStatus()
-    const {
+PrivacySandboxSettingsImpl::Status
+PrivacySandboxSettingsImpl::GetM1TopicAllowedStatus() const {
   return GetM1PrivacySandboxApiEnabledStatus(
       prefs::kPrivacySandboxM1TopicsEnabled);
 }
 
-bool PrivacySandboxSettings::IsTopicsAllowed() const {
+bool PrivacySandboxSettingsImpl::IsTopicsAllowed() const {
   // M1 specific
   if (base::FeatureList::IsEnabled(privacy_sandbox::kPrivacySandboxSettings4)) {
     Status status = GetM1TopicAllowedStatus();
@@ -129,7 +130,7 @@
   return IsPrivacySandboxEnabled() && !third_party_cookies_blocked;
 }
 
-bool PrivacySandboxSettings::IsTopicsAllowedForContext(
+bool PrivacySandboxSettingsImpl::IsTopicsAllowedForContext(
     const url::Origin& top_frame_origin,
     const GURL& url) const {
   // M1 specific
@@ -149,7 +150,7 @@
          IsPrivacySandboxEnabledForContext(top_frame_origin, url);
 }
 
-bool PrivacySandboxSettings::IsTopicAllowed(const CanonicalTopic& topic) {
+bool PrivacySandboxSettingsImpl::IsTopicAllowed(const CanonicalTopic& topic) {
   const auto& blocked_topics =
       pref_service_->GetList(prefs::kPrivacySandboxBlockedTopics);
 
@@ -167,8 +168,8 @@
   return true;
 }
 
-void PrivacySandboxSettings::SetTopicAllowed(const CanonicalTopic& topic,
-                                             bool allowed) {
+void PrivacySandboxSettingsImpl::SetTopicAllowed(const CanonicalTopic& topic,
+                                                 bool allowed) {
   ScopedListPrefUpdate scoped_pref_update(pref_service_,
                                           prefs::kPrivacySandboxBlockedTopics);
 
@@ -195,8 +196,8 @@
   }
 }
 
-void PrivacySandboxSettings::ClearTopicSettings(base::Time start_time,
-                                                base::Time end_time) {
+void PrivacySandboxSettingsImpl::ClearTopicSettings(base::Time start_time,
+                                                    base::Time end_time) {
   ScopedListPrefUpdate scoped_pref_update(pref_service_,
                                           prefs::kPrivacySandboxBlockedTopics);
 
@@ -213,13 +214,13 @@
   });
 }
 
-base::Time PrivacySandboxSettings::TopicsDataAccessibleSince() const {
+base::Time PrivacySandboxSettingsImpl::TopicsDataAccessibleSince() const {
   return pref_service_->GetTime(
       prefs::kPrivacySandboxTopicsDataAccessibleSince);
 }
 
-PrivacySandboxSettings::Status
-PrivacySandboxSettings::GetM1AttributionReportingAllowedStatus(
+PrivacySandboxSettingsImpl::Status
+PrivacySandboxSettingsImpl::GetM1AttributionReportingAllowedStatus(
     const url::Origin& top_frame_origin,
     const url::Origin& reporting_origin) const {
   Status status = GetM1PrivacySandboxApiEnabledStatus(
@@ -232,7 +233,7 @@
                                     reporting_origin.GetURL());
 }
 
-bool PrivacySandboxSettings::IsAttributionReportingAllowed(
+bool PrivacySandboxSettingsImpl::IsAttributionReportingAllowed(
     const url::Origin& top_frame_origin,
     const url::Origin& reporting_origin) const {
   // M1 specific
@@ -248,7 +249,7 @@
                                            reporting_origin.GetURL());
 }
 
-bool PrivacySandboxSettings::MaySendAttributionReport(
+bool PrivacySandboxSettingsImpl::MaySendAttributionReport(
     const url::Origin& source_origin,
     const url::Origin& destination_origin,
     const url::Origin& reporting_origin) const {
@@ -278,7 +279,7 @@
              reporting_origin.GetURL());
 }
 
-void PrivacySandboxSettings::SetFledgeJoiningAllowed(
+void PrivacySandboxSettingsImpl::SetFledgeJoiningAllowed(
     const std::string& top_frame_etld_plus1,
     bool allowed) {
   ScopedDictPrefUpdate scoped_pref_update(
@@ -323,7 +324,7 @@
   }
 }
 
-void PrivacySandboxSettings::ClearFledgeJoiningAllowedSettings(
+void PrivacySandboxSettingsImpl::ClearFledgeJoiningAllowedSettings(
     base::Time start_time,
     base::Time end_time) {
   ScopedDictPrefUpdate scoped_pref_update(
@@ -350,7 +351,7 @@
   }
 }
 
-bool PrivacySandboxSettings::IsFledgeJoiningAllowed(
+bool PrivacySandboxSettingsImpl::IsFledgeJoiningAllowed(
     const url::Origin& top_frame_origin) const {
   ScopedDictPrefUpdate scoped_pref_update(
       pref_service_, prefs::kPrivacySandboxFledgeJoinBlocked);
@@ -367,7 +368,8 @@
   return true;
 }
 
-PrivacySandboxSettings::Status PrivacySandboxSettings::GetM1FledgeAllowedStatus(
+PrivacySandboxSettingsImpl::Status
+PrivacySandboxSettingsImpl::GetM1FledgeAllowedStatus(
     const url::Origin& top_frame_origin,
     const url::Origin& auction_party) const {
   Status status = GetM1PrivacySandboxApiEnabledStatus(
@@ -379,7 +381,7 @@
   return GetSiteAccessAllowedStatus(top_frame_origin, auction_party.GetURL());
 }
 
-bool PrivacySandboxSettings::IsFledgeAllowed(
+bool PrivacySandboxSettingsImpl::IsFledgeAllowed(
     const url::Origin& top_frame_origin,
     const url::Origin& auction_party) const {
   if (base::FeatureList::IsEnabled(privacy_sandbox::kPrivacySandboxSettings4)) {
@@ -392,7 +394,7 @@
                                            auction_party.GetURL());
 }
 
-bool PrivacySandboxSettings::IsSharedStorageAllowed(
+bool PrivacySandboxSettingsImpl::IsSharedStorageAllowed(
     const url::Origin& top_frame_origin,
     const url::Origin& accessing_origin) const {
   if (base::FeatureList::IsEnabled(privacy_sandbox::kPrivacySandboxSettings4)) {
@@ -412,7 +414,7 @@
                                            accessing_origin.GetURL());
 }
 
-bool PrivacySandboxSettings::IsSharedStorageSelectURLAllowed(
+bool PrivacySandboxSettingsImpl::IsSharedStorageSelectURLAllowed(
     const url::Origin& top_frame_origin,
     const url::Origin& accessing_origin) const {
   if (base::FeatureList::IsEnabled(privacy_sandbox::kPrivacySandboxSettings4)) {
@@ -426,7 +428,7 @@
   return IsSharedStorageAllowed(top_frame_origin, accessing_origin);
 }
 
-bool PrivacySandboxSettings::IsPrivateAggregationAllowed(
+bool PrivacySandboxSettingsImpl::IsPrivateAggregationAllowed(
     const url::Origin& top_frame_origin,
     const url::Origin& reporting_origin) const {
   if (base::FeatureList::IsEnabled(privacy_sandbox::kPrivacySandboxSettings4)) {
@@ -441,8 +443,8 @@
                                            reporting_origin.GetURL());
 }
 
-bool PrivacySandboxSettings::IsPrivacySandboxEnabled() const {
-  PrivacySandboxSettings::Status status = GetPrivacySandboxAllowedStatus();
+bool PrivacySandboxSettingsImpl::IsPrivacySandboxEnabled() const {
+  PrivacySandboxSettingsImpl::Status status = GetPrivacySandboxAllowedStatus();
   if (!IsAllowed(status)) {
     return false;
   }
@@ -458,7 +460,7 @@
   return pref_service_->GetBoolean(prefs::kPrivacySandboxApisEnabledV2);
 }
 
-void PrivacySandboxSettings::SetAllPrivacySandboxAllowedForTesting() {
+void PrivacySandboxSettingsImpl::SetAllPrivacySandboxAllowedForTesting() {
   if (base::FeatureList::IsEnabled(privacy_sandbox::kPrivacySandboxSettings4)) {
     pref_service_->SetBoolean(prefs::kPrivacySandboxM1FledgeEnabled, true);
     pref_service_->SetBoolean(prefs::kPrivacySandboxM1TopicsEnabled, true);
@@ -470,7 +472,7 @@
   pref_service_->SetBoolean(prefs::kPrivacySandboxApisEnabledV2, true);
 }
 
-void PrivacySandboxSettings::SetTopicsBlockedForTesting() {
+void PrivacySandboxSettingsImpl::SetTopicsBlockedForTesting() {
   if (base::FeatureList::IsEnabled(privacy_sandbox::kPrivacySandboxSettings4)) {
     pref_service_->SetBoolean(prefs::kPrivacySandboxM1TopicsEnabled, false);
     return;
@@ -479,29 +481,29 @@
   pref_service_->SetBoolean(prefs::kPrivacySandboxApisEnabledV2, false);
 }
 
-void PrivacySandboxSettings::SetPrivacySandboxEnabled(bool enabled) {
+void PrivacySandboxSettingsImpl::SetPrivacySandboxEnabled(bool enabled) {
   pref_service_->SetBoolean(prefs::kPrivacySandboxApisEnabledV2, enabled);
 }
 
-bool PrivacySandboxSettings::IsTrustTokensAllowed() {
+bool PrivacySandboxSettingsImpl::IsTrustTokensAllowed() {
   return IsPrivacySandboxEnabled();
 }
 
-bool PrivacySandboxSettings::IsPrivacySandboxRestricted() const {
+bool PrivacySandboxSettingsImpl::IsPrivacySandboxRestricted() const {
   return delegate_->IsPrivacySandboxRestricted();
 }
 
-void PrivacySandboxSettings::OnCookiesCleared() {
+void PrivacySandboxSettingsImpl::OnCookiesCleared() {
   SetTopicsDataAccessibleFromNow();
 }
 
-void PrivacySandboxSettings::OnPrivacySandboxPrefChanged() {
+void PrivacySandboxSettingsImpl::OnPrivacySandboxPrefChanged() {
   for (auto& observer : observers_) {
     observer.OnTrustTokenBlockingChanged(!IsTrustTokensAllowed());
   }
 }
 
-void PrivacySandboxSettings::OnFirstPartySetsEnabledPrefChanged() {
+void PrivacySandboxSettingsImpl::OnFirstPartySetsEnabledPrefChanged() {
   if (!base::FeatureList::IsEnabled(features::kFirstPartySets)) {
     return;
   }
@@ -512,22 +514,20 @@
   }
 }
 
-void PrivacySandboxSettings::AddObserver(Observer* observer) {
+void PrivacySandboxSettingsImpl::AddObserver(Observer* observer) {
   observers_.AddObserver(observer);
 }
 
-void PrivacySandboxSettings::RemoveObserver(Observer* observer) {
+void PrivacySandboxSettingsImpl::RemoveObserver(Observer* observer) {
   observers_.RemoveObserver(observer);
 }
 
-void PrivacySandboxSettings::SetDelegateForTesting(
+void PrivacySandboxSettingsImpl::SetDelegateForTesting(
     std::unique_ptr<Delegate> delegate) {
   delegate_ = std::move(delegate);
 }
 
-PrivacySandboxSettings::PrivacySandboxSettings() = default;
-
-bool PrivacySandboxSettings::IsPrivacySandboxEnabledForContext(
+bool PrivacySandboxSettingsImpl::IsPrivacySandboxEnabledForContext(
     const absl::optional<url::Origin>& top_frame_origin,
     const GURL& url) const {
   if (!IsPrivacySandboxEnabled()) {
@@ -542,7 +542,7 @@
       content_settings::CookieSettings::QueryReason::kPrivacySandbox);
 }
 
-void PrivacySandboxSettings::SetTopicsDataAccessibleFromNow() const {
+void PrivacySandboxSettingsImpl::SetTopicsDataAccessibleFromNow() const {
   pref_service_->SetTime(prefs::kPrivacySandboxTopicsDataAccessibleSince,
                          base::Time::Now());
 
@@ -551,8 +551,8 @@
   }
 }
 
-PrivacySandboxSettings::Status
-PrivacySandboxSettings::GetSiteAccessAllowedStatus(
+PrivacySandboxSettingsImpl::Status
+PrivacySandboxSettingsImpl::GetSiteAccessAllowedStatus(
     const url::Origin& top_frame_origin,
     const GURL& url) const {
   // Relying on |host_content_settings_map_| instead of |cookie_settings_|
@@ -566,8 +566,8 @@
              : Status::kSiteDataAccessBlocked;
 }
 
-PrivacySandboxSettings::Status
-PrivacySandboxSettings::GetPrivacySandboxAllowedStatus() const {
+PrivacySandboxSettingsImpl::Status
+PrivacySandboxSettingsImpl::GetPrivacySandboxAllowedStatus() const {
   if (delegate_->IsIncognitoProfile()) {
     return Status::kIncognitoProfile;
   }
@@ -579,14 +579,14 @@
   return Status::kAllowed;
 }
 
-PrivacySandboxSettings::Status
-PrivacySandboxSettings::GetM1PrivacySandboxApiEnabledStatus(
+PrivacySandboxSettingsImpl::Status
+PrivacySandboxSettingsImpl::GetM1PrivacySandboxApiEnabledStatus(
     const std::string& pref_name) const {
   DCHECK(pref_name == prefs::kPrivacySandboxM1TopicsEnabled ||
          pref_name == prefs::kPrivacySandboxM1FledgeEnabled ||
          pref_name == prefs::kPrivacySandboxM1AdMeasurementEnabled);
 
-  PrivacySandboxSettings::Status status = GetPrivacySandboxAllowedStatus();
+  PrivacySandboxSettingsImpl::Status status = GetPrivacySandboxAllowedStatus();
   if (!IsAllowed(status)) {
     return status;
   }
diff --git a/components/privacy_sandbox/privacy_sandbox_settings_impl.h b/components/privacy_sandbox/privacy_sandbox_settings_impl.h
new file mode 100644
index 0000000..11d64a2
--- /dev/null
+++ b/components/privacy_sandbox/privacy_sandbox_settings_impl.h
@@ -0,0 +1,154 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PRIVACY_SANDBOX_PRIVACY_SANDBOX_SETTINGS_IMPL_H_
+#define COMPONENTS_PRIVACY_SANDBOX_PRIVACY_SANDBOX_SETTINGS_IMPL_H_
+
+#include "components/privacy_sandbox/privacy_sandbox_settings.h"
+
+#include "base/memory/raw_ptr.h"
+#include "base/observer_list.h"
+#include "base/time/time.h"
+#include "components/prefs/pref_change_registrar.h"
+
+class HostContentSettingsMap;
+class PrefService;
+
+namespace content_settings {
+class CookieSettings;
+}
+
+namespace privacy_sandbox {
+
+class PrivacySandboxSettingsImpl : public PrivacySandboxSettings {
+ public:
+  // Ideally the only external locations that call this constructor are the
+  // factory, and dedicated tests.
+  // TODO(crbug.com/1406840): Currently tests dedicated to other components rely
+  // on this interface, they should be migrated to something better (such as a
+  // dedicated test builder)
+  PrivacySandboxSettingsImpl(
+      std::unique_ptr<Delegate> delegate,
+      HostContentSettingsMap* host_content_settings_map,
+      scoped_refptr<content_settings::CookieSettings> cookie_settings,
+      PrefService* pref_service);
+  ~PrivacySandboxSettingsImpl() override;
+
+  // PrivacySandboxSettings:
+  bool IsTopicsAllowed() const override;
+  bool IsTopicsAllowedForContext(const url::Origin& top_frame_origin,
+                                 const GURL& url) const override;
+  bool IsTopicAllowed(const CanonicalTopic& topic) override;
+  void SetTopicAllowed(const CanonicalTopic& topic, bool allowed) override;
+  void ClearTopicSettings(base::Time start_time, base::Time end_time) override;
+  base::Time TopicsDataAccessibleSince() const override;
+  bool IsAttributionReportingAllowed(
+      const url::Origin& top_frame_origin,
+      const url::Origin& reporting_origin) const override;
+  bool MaySendAttributionReport(
+      const url::Origin& source_origin,
+      const url::Origin& destination_origin,
+      const url::Origin& reporting_origin) const override;
+  void SetFledgeJoiningAllowed(const std::string& top_frame_etld_plus1,
+                               bool allowed) override;
+  void ClearFledgeJoiningAllowedSettings(base::Time start_time,
+                                         base::Time end_time) override;
+  bool IsFledgeJoiningAllowed(
+      const url::Origin& top_frame_origin) const override;
+  bool IsFledgeAllowed(const url::Origin& top_frame_origin,
+                       const url::Origin& auction_party) const override;
+  bool IsSharedStorageAllowed(
+      const url::Origin& top_frame_origin,
+      const url::Origin& accessing_origin) const override;
+  bool IsSharedStorageSelectURLAllowed(
+      const url::Origin& top_frame_origin,
+      const url::Origin& accessing_origin) const override;
+  bool IsPrivateAggregationAllowed(
+      const url::Origin& top_frame_origin,
+      const url::Origin& reporting_origin) const override;
+  bool IsPrivacySandboxEnabled() const override;
+  void SetAllPrivacySandboxAllowedForTesting() override;
+  void SetTopicsBlockedForTesting() override;
+  void SetPrivacySandboxEnabled(bool enabled) override;
+  bool IsTrustTokensAllowed() override;
+  bool IsPrivacySandboxRestricted() const override;
+  void OnCookiesCleared() override;
+  void AddObserver(Observer* observer) override;
+  void RemoveObserver(Observer* observer) override;
+  void SetDelegateForTesting(std::unique_ptr<Delegate> delegate) override;
+
+ private:
+  friend class PrivacySandboxSettingsM1Test;
+  // Called when the main privacy sandbox preference is changed.
+  void OnPrivacySandboxPrefChanged();
+
+  // Called when the First-Party Sets enabled preference is changed.
+  void OnFirstPartySetsEnabledPrefChanged();
+
+  // Determines based on the current features, preferences and provided
+  // |cookie_settings| whether Privacy Sandbox APIs are generally allowable for
+  // |url| on |top_frame_origin|. Individual APIs may perform additional checks
+  // for allowability (such as incognito) on top of this. |cookie_settings| is
+  // provided as a parameter to allow callers to cache it between calls.
+  bool IsPrivacySandboxEnabledForContext(
+      const absl::optional<url::Origin>& top_frame_origin,
+      const GURL& url) const;
+
+  void SetTopicsDataAccessibleFromNow() const;
+
+  // These values are persisted to logs. Entries should not be renumbered and
+  // numeric values should never be reused.
+  enum class Status {
+    kAllowed,
+    kRestricted,
+    kIncognitoProfile,
+    kApisDisabled,
+    kSiteDataAccessBlocked,
+    kMaxValue = kSiteDataAccessBlocked,
+  };
+
+  static bool IsAllowed(Status status);
+
+  // Whether the site associated with the URL is allowed to access privacy
+  // sandbox APIs within the context of |top_frame_origin|.
+  Status GetSiteAccessAllowedStatus(const url::Origin& top_frame_origin,
+                                    const GURL& url) const;
+
+  // Whether the privacy sandbox APIs can be allowed given the current
+  // environment. For example, the privacy sandbox is always disabled in
+  // Incognito and for restricted accounts.
+  Status GetPrivacySandboxAllowedStatus() const;
+
+  // Whether the privacy sandbox associated with  the |pref_name| is enabled.
+  // For individual sites, check as well with GetSiteAccessAllowedStatus.
+  Status GetM1PrivacySandboxApiEnabledStatus(
+      const std::string& pref_name) const;
+
+  // Whether the Topics API can be allowed given the current
+  // environment or the reason why it is not allowed.
+  Status GetM1TopicAllowedStatus() const;
+
+  // Whether Attribution Reporting API can be allowed given the current
+  // environment or the reason why it is not allowed.
+  Status GetM1AttributionReportingAllowedStatus(
+      const url::Origin& top_frame_origin,
+      const url::Origin& reporting_origin) const;
+
+  // Whether Fledge can be allowed given the current environment or the reason
+  // why it is not allowed.
+  Status GetM1FledgeAllowedStatus(const url::Origin& top_frame_origin,
+                                  const url::Origin& accessing_origin) const;
+
+  base::ObserverList<Observer>::Unchecked observers_;
+
+  std::unique_ptr<Delegate> delegate_;
+  raw_ptr<HostContentSettingsMap, DanglingUntriaged> host_content_settings_map_;
+  scoped_refptr<content_settings::CookieSettings> cookie_settings_;
+  raw_ptr<PrefService, DanglingUntriaged> pref_service_;
+  PrefChangeRegistrar pref_change_registrar_;
+};
+
+}  // namespace privacy_sandbox
+
+#endif  // COMPONENTS_PRIVACY_SANDBOX_PRIVACY_SANDBOX_SETTINGS_IMPL_H_
diff --git a/components/privacy_sandbox/privacy_sandbox_settings_unittest.cc b/components/privacy_sandbox/privacy_sandbox_settings_impl_unittest.cc
similarity index 99%
rename from components/privacy_sandbox/privacy_sandbox_settings_unittest.cc
rename to components/privacy_sandbox/privacy_sandbox_settings_impl_unittest.cc
index b2bce31..3303d0a 100644
--- a/components/privacy_sandbox/privacy_sandbox_settings_unittest.cc
+++ b/components/privacy_sandbox/privacy_sandbox_settings_impl_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 "components/privacy_sandbox/privacy_sandbox_settings.h"
+#include "components/privacy_sandbox/privacy_sandbox_settings_impl.h"
 
 #include "base/json/values_util.h"
 #include "base/test/gtest_util.h"
@@ -139,7 +139,7 @@
     InitializeFeaturesBeforeStart();
     InitializeDelegateBeforeStart();
 
-    privacy_sandbox_settings_ = std::make_unique<PrivacySandboxSettings>(
+    privacy_sandbox_settings_ = std::make_unique<PrivacySandboxSettingsImpl>(
         std::move(mock_delegate), host_content_settings_map(), cookie_settings_,
         prefs());
   }
@@ -1008,7 +1008,7 @@
   }
 
  protected:
-  using Status = PrivacySandboxSettings::Status;
+  using Status = PrivacySandboxSettingsImpl::Status;
 
   void RunTestCase(const TestState& test_state,
                    const TestInput& test_input,
diff --git a/components/services/storage/indexed_db/locks/partitioned_lock_manager.cc b/components/services/storage/indexed_db/locks/partitioned_lock_manager.cc
index bf33b351..d222953 100644
--- a/components/services/storage/indexed_db/locks/partitioned_lock_manager.cc
+++ b/components/services/storage/indexed_db/locks/partitioned_lock_manager.cc
@@ -117,6 +117,21 @@
                                           : TestLockResult::kLocked;
 }
 
+std::vector<PartitionedLockId> PartitionedLockManager::GetUnacquirableLocks(
+    std::vector<PartitionedLockRequest>& lock_requests) {
+  std::vector<PartitionedLockId> lock_ids;
+  for (PartitionedLockRequest& request : lock_requests) {
+    auto it = locks_.find(request.lock_id);
+    if (it != locks_.end()) {
+      Lock& lock = it->second;
+      if (!lock.CanBeAcquired(request.type)) {
+        lock_ids.push_back(request.lock_id);
+      }
+    }
+  }
+  return lock_ids;
+}
+
 void PartitionedLockManager::RemoveLockId(const PartitionedLockId& lock_id) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   auto it = locks_.find(lock_id);
diff --git a/components/services/storage/indexed_db/locks/partitioned_lock_manager.h b/components/services/storage/indexed_db/locks/partitioned_lock_manager.h
index 3e15fea..5b233da 100644
--- a/components/services/storage/indexed_db/locks/partitioned_lock_manager.h
+++ b/components/services/storage/indexed_db/locks/partitioned_lock_manager.h
@@ -7,6 +7,8 @@
 
 #include <iosfwd>
 #include <list>
+#include <memory>
+#include <set>
 #include <vector>
 
 #include "base/component_export.h"
@@ -95,6 +97,12 @@
   // Tests to see if the given lock request can be acquired.
   TestLockResult TestLock(PartitionedLockRequest lock_requests);
 
+  // Filter out the list of `PartitionedLockId`s that cannot be acquired given
+  // the list of `PartitionedLockRequest`.
+  // See `Lock::CanBeAcquired()`.
+  std::vector<PartitionedLockId> GetUnacquirableLocks(
+      std::vector<PartitionedLockRequest>& lock_requests);
+
   // Remove the given lock lock_id. The lock lock_id must not be in use. Call
   // this if the lock will never be used again.
   void RemoveLockId(const PartitionedLockId& lock_id);
diff --git a/components/translate/content/common/translate.mojom b/components/translate/content/common/translate.mojom
index 175287e..e58264a 100644
--- a/components/translate/content/common/translate.mojom
+++ b/components/translate/content/common/translate.mojom
@@ -24,12 +24,12 @@
   TRANSLATE_ERROR_MAX,
 };
 
-// This struct is populated a TranslateAgent to inform the browser about the
+// This struct is populated by a TranslateAgent to inform the browser about the
 // result of the language detection model. Corresponds to
 // LanguageDetectionDetails defined in language_detection_details.h.
 struct LanguageDetectionDetails {
-  // All the elements in this section are used for to make decisions related
-  // to page translation.
+  // All the elements in this section are used for making decisions related to
+  // page translation.
   //
   // The URL corresponding to the main frame that had its language detected.
   // Used by the TranslateDriver to determine if the page is eligible for
@@ -47,6 +47,9 @@
   // All the elements below are used only for debugging and metrics purposes,
   // e.g., translate-internals.
   //
+  // Whether language detection has been run on the page. Under
+  // kRetryLanguageDetection, this is only done if page content was captured.
+  bool has_run_lang_detection;
   // The time at which language the language detection was performed. Used only
   // for debugging.
   mojo_base.mojom.Time time;
diff --git a/components/translate/content/common/translate_mojom_traits.cc b/components/translate/content/common/translate_mojom_traits.cc
index a296409..bdae728 100644
--- a/components/translate/content/common/translate_mojom_traits.cc
+++ b/components/translate/content/common/translate_mojom_traits.cc
@@ -95,6 +95,8 @@
                   translate::LanguageDetectionDetails>::
     Read(translate::mojom::LanguageDetectionDetailsDataView data,
          translate::LanguageDetectionDetails* out) {
+  out->has_run_lang_detection = data.has_run_lang_detection();
+
   if (!data.ReadTime(&out->time))
     return false;
   if (!data.ReadUrl(&out->url))
diff --git a/components/translate/content/common/translate_mojom_traits.h b/components/translate/content/common/translate_mojom_traits.h
index aaa0d90..6bc8615 100644
--- a/components/translate/content/common/translate_mojom_traits.h
+++ b/components/translate/content/common/translate_mojom_traits.h
@@ -27,6 +27,11 @@
 template <>
 struct StructTraits<translate::mojom::LanguageDetectionDetailsDataView,
                     translate::LanguageDetectionDetails> {
+  static bool has_run_lang_detection(
+      const translate::LanguageDetectionDetails& r) {
+    return r.has_run_lang_detection;
+  }
+
   static const base::Time& time(const translate::LanguageDetectionDetails& r) {
     return r.time;
   }
diff --git a/components/translate/content/renderer/translate_agent.cc b/components/translate/content/renderer/translate_agent.cc
index 9a09f24..558741bf 100644
--- a/components/translate/content/renderer/translate_agent.cc
+++ b/components/translate/content/renderer/translate_agent.cc
@@ -161,11 +161,16 @@
 }
 
 void TranslateAgent::PrepareForUrl(const GURL& url) {
-  // Navigated to a new url, reset current page translation.
+  // Navigated to a new url, reset current page translation and related state.
+  page_contents_length_ = 0;
   ResetPage();
 }
 
 void TranslateAgent::PageCaptured(const std::u16string& contents) {
+  // This method should only be called if it was not already run on captured
+  // content on the page.
+  DCHECK(!WasPageContentCapturedForUrl());
+
   // Get the document language as set by WebKit from the http-equiv
   // meta tag for "content-language".  This may or may not also
   // have a value derived from the actual Content-Language HTTP
@@ -220,8 +225,14 @@
     return;
   }
 
+  LanguageDetectionDetails details;
   std::string language;
-  if (translate::IsTFLiteLanguageDetectionEnabled()) {
+  if (base::FeatureList::IsEnabled(translate::kRetryLanguageDetection) &&
+      page_contents_length_ == 0) {
+    // Under kRetryLanguageDetection, if captured content is empty,
+    // default to using "und" instead of attempting language detection.
+    language = translate::kUnknownLanguageCode;
+  } else if (translate::IsTFLiteLanguageDetectionEnabled()) {
     translate::LanguageDetectionModel& language_detection_model =
         GetLanguageDetectionModel();
     bool is_available = language_detection_model.IsAvailable();
@@ -237,11 +248,13 @@
         "LanguageDetection.TFLiteModel.WasModelUnavailableDueToDeferredLoad",
         !is_available && waiting_for_first_foreground_);
     detection_model_version = language_detection_model.GetModelVersion();
+    details.has_run_lang_detection = true;
   } else {
     language = DeterminePageLanguage(
         content_language, html_lang, contents, &model_detected_language,
         &is_model_reliable, model_reliability_score);
     detection_model_version = kCLDModelVersion;
+    details.has_run_lang_detection = true;
   }
 
   if (language.empty())
@@ -251,7 +264,6 @@
 
   // TODO(crbug.com/1157983): Update the language detection details struct to be
   // model agnostic.
-  LanguageDetectionDetails details;
   details.time = base::Time::Now();
   details.url = web_detection_details.url;
   details.content_language = content_language;
diff --git a/components/translate/content/renderer/translate_agent.h b/components/translate/content/renderer/translate_agent.h
index 024ae94..5396d5e 100644
--- a/components/translate/content/renderer/translate_agent.h
+++ b/components/translate/content/renderer/translate_agent.h
@@ -52,6 +52,11 @@
   // this URL loads, this is the time to prepare for it.
   void PrepareForUrl(const GURL& url);
 
+  // Under kRetryLanguageDetection, this is true if a previous call to
+  // PageCaptured has been made with captured page content and language
+  // detection was run.
+  bool WasPageContentCapturedForUrl() { return page_contents_length_; }
+
   // mojom::TranslateAgent implementation.
   void GetWebLanguageDetectionDetails(
       GetWebLanguageDetectionDetailsCallback callback) override;
diff --git a/components/translate/core/common/language_detection_details.h b/components/translate/core/common/language_detection_details.h
index 12a4a71..a602710 100644
--- a/components/translate/core/common/language_detection_details.h
+++ b/components/translate/core/common/language_detection_details.h
@@ -12,11 +12,16 @@
 
 namespace translate {
 
+// This struct corresponds to LanguageDetectionDetails defined in
+// translate.mojom, any changes need to be made to both definitions.
 struct LanguageDetectionDetails {
   LanguageDetectionDetails();
   LanguageDetectionDetails(const LanguageDetectionDetails& other);
   ~LanguageDetectionDetails();
 
+  // Whether language detection has been run on the page.
+  bool has_run_lang_detection = false;
+
   // The time when this was created.
   base::Time time;
 
diff --git a/components/translate/core/common/translate_util.cc b/components/translate/core/common/translate_util.cc
index 746a441..aa7464d 100644
--- a/components/translate/core/common/translate_util.cc
+++ b/components/translate/core/common/translate_util.cc
@@ -60,6 +60,10 @@
 const base::FeatureParam<int> kDesktopPartialTranslateBubbleShowDelayMs{
     &kDesktopPartialTranslate, "DesktopPartialTranslateBubbleShowDelayMs", 500};
 
+BASE_FEATURE(kRetryLanguageDetection,
+             "RetryLanguageDetection",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 #if !BUILDFLAG(IS_WIN)
 BASE_FEATURE(kMmapLanguageDetectionModel,
              "MmapLanguageDetectionModel",
diff --git a/components/translate/core/common/translate_util.h b/components/translate/core/common/translate_util.h
index c448e8e..7b6528b 100644
--- a/components/translate/core/common/translate_util.h
+++ b/components/translate/core/common/translate_util.h
@@ -37,6 +37,9 @@
 // is shown.
 extern const base::FeatureParam<int> kDesktopPartialTranslateBubbleShowDelayMs;
 
+// Controls whether language detection improvements are in effect
+BASE_DECLARE_FEATURE(kRetryLanguageDetection);
+
 #if !BUILDFLAG(IS_WIN)
 // Controls whether mmap is used to load the language detection model.
 BASE_DECLARE_FEATURE(kMmapLanguageDetectionModel);
diff --git a/components/translate/translate_internals/translate_internals.js b/components/translate/translate_internals/translate_internals.js
index cc6fbe6..1331330 100644
--- a/components/translate/translate_internals/translate_internals.js
+++ b/components/translate/translate_internals/translate_internals.js
@@ -373,6 +373,17 @@
 
   const tr = document.createElement('tr');
 
+  // If language detection was skipped, do not populate related details.
+  const hasRunLangDetection = JSON.parse(detail['has_run_lang_detection']);
+  const cldLang = hasRunLangDetection ?
+      formatLanguageCode(detail['model_detected_language']) :
+      'No page content - language detection skipped';
+  const modelVersion =
+      hasRunLangDetection ? detail['detection_model_version'] : '';
+  const reliabilityScore =
+      hasRunLangDetection ? detail['model_reliability_score'].toFixed(2) : '';
+  const isReliable = hasRunLangDetection ? detail['is_model_reliable'] : '';
+
   appendTD(tr, formatDate(new Date(detail['time'])), 'detection-logs-time');
   appendTD(tr, detail['url'], 'detection-logs-url');
   appendTD(
@@ -381,16 +392,10 @@
   appendTD(
       tr, formatLanguageCode(detail['html_root_language']),
       'detection-logs-html-root-language');
-  appendTD(
-      tr, formatLanguageCode(detail['model_detected_language']),
-      'detection-logs-cld-language');
-  appendTD(
-      tr, detail['detection_model_version'],
-      'detection-logs-detection-model-version');
-  appendTD(
-      tr, detail['model_reliability_score'].toFixed(2),
-      'detection-logs-model-reliability');
-  appendTD(tr, detail['is_model_reliable'], 'detection-logs-is-cld-reliable');
+  appendTD(tr, cldLang, 'detection-logs-cld-language');
+  appendTD(tr, modelVersion, 'detection-logs-detection-model-version');
+  appendTD(tr, reliabilityScore, 'detection-logs-model-reliability');
+  appendTD(tr, isReliable, 'detection-logs-is-cld-reliable');
   appendTD(tr, detail['has_notranslate'], 'detection-logs-has-notranslate');
   appendTD(
       tr, formatLanguageCode(detail['adopted_language']),
diff --git a/components/translate/translate_internals/translate_internals_handler.cc b/components/translate/translate_internals/translate_internals_handler.cc
index 72e52a9..0da9a03 100644
--- a/components/translate/translate_internals/translate_internals_handler.cc
+++ b/components/translate/translate_internals/translate_internals_handler.cc
@@ -91,6 +91,7 @@
 void TranslateInternalsHandler::AddLanguageDetectionDetails(
     const translate::LanguageDetectionDetails& details) {
   base::Value::Dict dict;
+  dict.Set("has_run_lang_detection", details.has_run_lang_detection);
   dict.Set("time", details.time.ToJsTime());
   dict.Set("url", details.url.spec());
   dict.Set("content_language", details.content_language);
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index d765937..f72f60e 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -420,8 +420,6 @@
     "attribution_reporting/attribution_data_host_manager_impl.h",
     "attribution_reporting/attribution_debug_report.cc",
     "attribution_reporting/attribution_debug_report.h",
-    "attribution_reporting/attribution_default_random_generator.cc",
-    "attribution_reporting/attribution_default_random_generator.h",
     "attribution_reporting/attribution_header_utils.cc",
     "attribution_reporting/attribution_header_utils.h",
     "attribution_reporting/attribution_host.cc",
@@ -443,7 +441,6 @@
     "attribution_reporting/attribution_observer.h",
     "attribution_reporting/attribution_observer_types.cc",
     "attribution_reporting/attribution_observer_types.h",
-    "attribution_reporting/attribution_random_generator.h",
     "attribution_reporting/attribution_report.cc",
     "attribution_reporting/attribution_report.h",
     "attribution_reporting/attribution_report_network_sender.cc",
@@ -473,6 +470,7 @@
     "attribution_reporting/rate_limit_table.cc",
     "attribution_reporting/rate_limit_table.h",
     "attribution_reporting/send_result.h",
+    "attribution_reporting/sql_queries.h",
     "attribution_reporting/sql_utils.cc",
     "attribution_reporting/sql_utils.h",
     "attribution_reporting/storable_source.cc",
diff --git a/content/browser/attribution_reporting/BUILD.gn b/content/browser/attribution_reporting/BUILD.gn
index 1fab8be..d1082c26 100644
--- a/content/browser/attribution_reporting/BUILD.gn
+++ b/content/browser/attribution_reporting/BUILD.gn
@@ -57,3 +57,21 @@
     },
   ]
 }
+
+# Platforms where sqlite_dev_shell is defined.
+if (is_win || is_mac || is_linux || is_chromeos) {
+  source_set("sqlite_test_utils") {
+    testonly = true
+    sources = [
+      "sql_query_plan_test_util.cc",
+      "sql_query_plan_test_util.h",
+    ]
+
+    deps = [
+      "//base",
+      "//testing/gtest",
+    ]
+
+    data_deps = [ "//third_party/sqlite:sqlite_dev_shell" ]
+  }
+}
diff --git a/content/browser/attribution_reporting/attribution_default_random_generator.cc b/content/browser/attribution_reporting/attribution_default_random_generator.cc
deleted file mode 100644
index d0f588c1..0000000
--- a/content/browser/attribution_reporting/attribution_default_random_generator.cc
+++ /dev/null
@@ -1,25 +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.
-
-#include "content/browser/attribution_reporting/attribution_default_random_generator.h"
-
-#include "base/rand_util.h"
-#include "content/browser/attribution_reporting/attribution_report.h"
-
-namespace content {
-
-double AttributionDefaultRandomGenerator::RandDouble() {
-  return base::RandDouble();
-}
-
-int AttributionDefaultRandomGenerator::RandInt(int min, int max) {
-  return base::RandInt(min, max);
-}
-
-void AttributionDefaultRandomGenerator::RandomShuffle(
-    std::vector<AttributionReport>& reports) {
-  base::RandomShuffle(reports.begin(), reports.end());
-}
-
-}  // namespace content
diff --git a/content/browser/attribution_reporting/attribution_default_random_generator.h b/content/browser/attribution_reporting/attribution_default_random_generator.h
deleted file mode 100644
index 6b4a8b4d..0000000
--- a/content/browser/attribution_reporting/attribution_default_random_generator.h
+++ /dev/null
@@ -1,39 +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.
-
-#ifndef CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_DEFAULT_RANDOM_GENERATOR_H_
-#define CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_DEFAULT_RANDOM_GENERATOR_H_
-
-#include "content/browser/attribution_reporting/attribution_random_generator.h"
-#include "content/common/content_export.h"
-
-namespace content {
-
-// Uses the secure top-level functions of the same name in `base/rand_util.h`.
-class CONTENT_EXPORT AttributionDefaultRandomGenerator
-    : public AttributionRandomGenerator {
- public:
-  AttributionDefaultRandomGenerator() = default;
-
-  ~AttributionDefaultRandomGenerator() override = default;
-
-  AttributionDefaultRandomGenerator(const AttributionDefaultRandomGenerator&) =
-      delete;
-  AttributionDefaultRandomGenerator(AttributionDefaultRandomGenerator&&) =
-      delete;
-
-  AttributionDefaultRandomGenerator& operator=(
-      const AttributionDefaultRandomGenerator&) = delete;
-  AttributionDefaultRandomGenerator& operator=(
-      AttributionDefaultRandomGenerator&&) = delete;
-
-  // AttributionRandomGenerator:
-  double RandDouble() override;
-  int RandInt(int min, int max) override;
-  void RandomShuffle(std::vector<AttributionReport>& reports) override;
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_DEFAULT_RANDOM_GENERATOR_H_
diff --git a/content/browser/attribution_reporting/attribution_insecure_random_generator.cc b/content/browser/attribution_reporting/attribution_insecure_random_generator.cc
deleted file mode 100644
index e24a149..0000000
--- a/content/browser/attribution_reporting/attribution_insecure_random_generator.cc
+++ /dev/null
@@ -1,112 +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.
-
-#include "content/browser/attribution_reporting/attribution_insecure_random_generator.h"
-
-#include <stdint.h>
-
-#include <limits>
-
-#include "base/bit_cast.h"
-#include "base/check_op.h"
-#include "base/memory/raw_ref.h"
-#include "base/ranges/algorithm.h"
-#include "content/browser/attribution_reporting/attribution_report.h"
-#include "third_party/abseil-cpp/absl/numeric/int128.h"
-
-namespace content {
-
-namespace {
-
-// Copied from `v8::base::RandomNumberGenerator::XorShift128()`.
-void XorShift128(uint64_t* state0, uint64_t* state1) {
-  uint64_t s1 = *state0;
-  uint64_t s0 = *state1;
-  *state0 = s0;
-  s1 ^= s1 << 23;
-  s1 ^= s1 >> 17;
-  s1 ^= s0;
-  s1 ^= s0 >> 26;
-  *state1 = s1;
-}
-
-// Copied from `v8::base::RandomNumberGenerator::ToDouble()`.
-double ToDouble(uint64_t state0) {
-  // Exponent for double values for [1.0 .. 2.0)
-  static const uint64_t kExponentBits = uint64_t{0x3FF0000000000000};
-  uint64_t random = (state0 >> 12) | kExponentBits;
-  return base::bit_cast<double>(random) - 1;
-}
-
-}  // namespace
-
-AttributionInsecureRandomGenerator::AttributionInsecureRandomGenerator(
-    absl::uint128 seed)
-    : state0_(absl::Uint128Low64(seed)), state1_(absl::Uint128High64(seed)) {}
-
-// Adapted from `v8::base::RandomNumberGenerator::NextInt64()`.
-uint64_t AttributionInsecureRandomGenerator::RandUint64() {
-  XorShift128(&state0_, &state1_);
-  return state0_ + state1_;
-}
-
-// Copied from `v8::base::RandomNumberGenerator::ToDouble()`.
-double AttributionInsecureRandomGenerator::RandDouble() {
-  XorShift128(&state0_, &state1_);
-  double result = ToDouble(state0_);
-  DCHECK_GE(result, 0.0);
-  DCHECK_LT(result, 1.0);
-  return result;
-}
-
-// Adapted from `base::RandGenerator()`.
-uint64_t AttributionInsecureRandomGenerator::RandGenerator(uint64_t range) {
-  DCHECK_GT(range, 0u);
-  // We must discard random results above this number, as they would
-  // make the random generator non-uniform (consider e.g. if
-  // MAX_UINT64 was 7 and |range| was 5, then a result of 1 would be twice
-  // as likely as a result of 3 or 4).
-  uint64_t max_acceptable_value =
-      (std::numeric_limits<uint64_t>::max() / range) * range - 1;
-
-  uint64_t value;
-  do {
-    value = RandUint64();
-  } while (value > max_acceptable_value);
-
-  return value % range;
-}
-
-// Adapted from `base::RandInt()`.
-int AttributionInsecureRandomGenerator::RandInt(int min, int max) {
-  DCHECK_LE(min, max);
-
-  uint64_t range = static_cast<uint64_t>(max) - min + 1;
-  // |range| is at most UINT_MAX + 1, so the result of `RandGenerator(range)`
-  // is at most UINT_MAX.  Hence it's safe to cast it from uint64_t to int64_t.
-  int result =
-      static_cast<int>(min + static_cast<int64_t>(RandGenerator(range)));
-  DCHECK_GE(result, min);
-  DCHECK_LE(result, max);
-  return result;
-}
-
-// Adapted from `base::RandomBitGenerator` and `base::RandomShuffle()`.
-void AttributionInsecureRandomGenerator::RandomShuffle(
-    std::vector<AttributionReport>& reports) {
-  struct RandomBitGenerator {
-    using result_type = uint64_t;
-    static constexpr result_type min() { return 0; }
-    static constexpr result_type max() {
-      return std::numeric_limits<uint64_t>::max();
-    }
-    result_type operator()() const { return gen->RandUint64(); }
-
-    const raw_ref<AttributionInsecureRandomGenerator> gen;
-  };
-
-  base::ranges::shuffle(reports, RandomBitGenerator{.gen = raw_ref(*this)});
-}
-
-}  // namespace content
diff --git a/content/browser/attribution_reporting/attribution_insecure_random_generator.h b/content/browser/attribution_reporting/attribution_insecure_random_generator.h
deleted file mode 100644
index 9340bd6..0000000
--- a/content/browser/attribution_reporting/attribution_insecure_random_generator.h
+++ /dev/null
@@ -1,51 +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.
-
-#ifndef CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_INSECURE_RANDOM_GENERATOR_H_
-#define CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_INSECURE_RANDOM_GENERATOR_H_
-
-#include <stdint.h>
-
-#include "content/browser/attribution_reporting/attribution_random_generator.h"
-
-namespace absl {
-class uint128;
-}  // namespace absl
-
-namespace content {
-
-// A test-only insecure random number generator that uses XorShift128+
-// internally.
-class AttributionInsecureRandomGenerator : public AttributionRandomGenerator {
- public:
-  explicit AttributionInsecureRandomGenerator(absl::uint128 seed);
-
-  AttributionInsecureRandomGenerator(
-      const AttributionInsecureRandomGenerator&) = delete;
-  AttributionInsecureRandomGenerator(AttributionInsecureRandomGenerator&&) =
-      delete;
-
-  AttributionInsecureRandomGenerator& operator=(
-      const AttributionInsecureRandomGenerator&) = delete;
-  AttributionInsecureRandomGenerator& operator=(
-      AttributionInsecureRandomGenerator&&) = delete;
-
-  // AttributionStorageDelegateImpl::RandomGenerator:
-  double RandDouble() override;
-  int RandInt(int min, int max) override;
-  void RandomShuffle(std::vector<AttributionReport>& reports) override;
-
- private:
-  uint64_t RandUint64();
-
-  // Returns a random number in range [0, range).
-  uint64_t RandGenerator(uint64_t range);
-
-  uint64_t state0_;
-  uint64_t state1_;
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_INSECURE_RANDOM_GENERATOR_H_
diff --git a/content/browser/attribution_reporting/attribution_insecure_random_generator_unittest.cc b/content/browser/attribution_reporting/attribution_insecure_random_generator_unittest.cc
deleted file mode 100644
index 2ace97bd..0000000
--- a/content/browser/attribution_reporting/attribution_insecure_random_generator_unittest.cc
+++ /dev/null
@@ -1,77 +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.
-
-#include "content/browser/attribution_reporting/attribution_insecure_random_generator.h"
-
-#include <vector>
-
-#include "content/browser/attribution_reporting/attribution_report.h"
-#include "content/browser/attribution_reporting/attribution_test_utils.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/numeric/int128.h"
-
-namespace content {
-namespace {
-
-using ::testing::ElementsAre;
-using ::testing::Ge;
-using ::testing::Le;
-using ::testing::Lt;
-
-// These tests use empirically determined golden data based on the seed below.
-class AttributionInsecureRandomGeneratorTest : public ::testing::Test {
- protected:
-  AttributionInsecureRandomGenerator gen_{absl::MakeUint128(0xabcd, 0x1234)};
-};
-
-TEST_F(AttributionInsecureRandomGeneratorTest, RandDouble) {
-  const double kExpected[] = {
-      0x1.4p-49,           0x1.234086p-29,      0x1.73f2b98p-26,
-      0x1.23400246c8fcp-6, 0x1.579a02e7b3c3p-3,
-  };
-
-  for (double expected : kExpected) {
-    const double actual = gen_.RandDouble();
-    EXPECT_THAT(actual, Ge(0));
-    EXPECT_THAT(actual, Lt(1));
-    EXPECT_EQ(actual, expected);
-  }
-}
-
-TEST_F(AttributionInsecureRandomGeneratorTest, RandInt) {
-  const int kMin = 2;
-  const int kMax = 11;
-
-  const int kExpected[] = {8, 5, 2, 3, 10};
-
-  for (int expected : kExpected) {
-    const int actual = gen_.RandInt(kMin, kMax);
-    EXPECT_THAT(actual, Ge(kMin));
-    EXPECT_THAT(actual, Le(kMax));
-    EXPECT_EQ(actual, expected);
-  }
-}
-
-TEST_F(AttributionInsecureRandomGeneratorTest, RandomShuffle) {
-  ReportBuilder builder(
-      AttributionInfoBuilder(SourceBuilder().BuildStored()).Build());
-
-  std::vector<AttributionReport> reports = {
-      builder.SetTriggerData(1).Build(), builder.SetTriggerData(2).Build(),
-      builder.SetTriggerData(3).Build(), builder.SetTriggerData(4).Build(),
-      builder.SetTriggerData(5).Build(),
-  };
-
-  gen_.RandomShuffle(reports);
-
-  EXPECT_THAT(reports, ElementsAre(EventLevelDataIs(TriggerDataIs(4)),
-                                   EventLevelDataIs(TriggerDataIs(2)),
-                                   EventLevelDataIs(TriggerDataIs(3)),
-                                   EventLevelDataIs(TriggerDataIs(5)),
-                                   EventLevelDataIs(TriggerDataIs(1))));
-}
-
-}  // namespace
-}  // namespace content
diff --git a/content/browser/attribution_reporting/attribution_random_generator.h b/content/browser/attribution_reporting/attribution_random_generator.h
deleted file mode 100644
index 57a7be9..0000000
--- a/content/browser/attribution_reporting/attribution_random_generator.h
+++ /dev/null
@@ -1,36 +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.
-
-#ifndef CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_RANDOM_GENERATOR_H_
-#define CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_RANDOM_GENERATOR_H_
-
-#include <vector>
-
-namespace content {
-
-class AttributionReport;
-
-// Provides randomness to an `AttributionStorageDelegateImpl`.
-//
-// TODO(apaseltiner): Consider reconciling this interface with the APIs exposed
-// in `base/rand_util.h`. Perhaps just a `UniformRandomBitGenerator` and a suite
-// of helper functions which provide `RandDouble()`, `RandInt()`, etc with the
-// generator as input, like `base::ranges::shuffle()`.
-class AttributionRandomGenerator {
- public:
-  virtual ~AttributionRandomGenerator() = default;
-
-  // Returns a random double in the range [0, 1).
-  virtual double RandDouble() = 0;
-
-  // Returns a random int in the range [min, max].
-  virtual int RandInt(int min, int max) = 0;
-
-  // Shuffles `reports` randomly.
-  virtual void RandomShuffle(std::vector<AttributionReport>& reports) = 0;
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_RANDOM_GENERATOR_H_
diff --git a/content/browser/attribution_reporting/attribution_storage_delegate_impl.cc b/content/browser/attribution_reporting/attribution_storage_delegate_impl.cc
index 745ca39..d19e9ea3 100644
--- a/content/browser/attribution_reporting/attribution_storage_delegate_impl.cc
+++ b/content/browser/attribution_reporting/attribution_storage_delegate_impl.cc
@@ -14,8 +14,6 @@
 #include "base/memory/ptr_util.h"
 #include "base/rand_util.h"
 #include "base/time/time.h"
-#include "content/browser/attribution_reporting/attribution_default_random_generator.h"
-#include "content/browser/attribution_reporting/attribution_random_generator.h"
 #include "content/browser/attribution_reporting/attribution_report.h"
 #include "content/browser/attribution_reporting/attribution_utils.h"
 #include "content/browser/attribution_reporting/combinatorics.h"
@@ -30,32 +28,25 @@
 AttributionStorageDelegateImpl::CreateForTesting(
     AttributionNoiseMode noise_mode,
     AttributionDelayMode delay_mode,
-    const AttributionConfig& config,
-    std::unique_ptr<AttributionRandomGenerator> rng) {
-  return base::WrapUnique(new AttributionStorageDelegateImpl(
-      noise_mode, delay_mode, config, std::move(rng)));
+    const AttributionConfig& config) {
+  return base::WrapUnique(
+      new AttributionStorageDelegateImpl(noise_mode, delay_mode, config));
 }
 
 AttributionStorageDelegateImpl::AttributionStorageDelegateImpl(
     AttributionNoiseMode noise_mode,
     AttributionDelayMode delay_mode)
-    : AttributionStorageDelegateImpl(
-          noise_mode,
-          delay_mode,
-          AttributionConfig(),
-          std::make_unique<AttributionDefaultRandomGenerator>()) {}
+    : AttributionStorageDelegateImpl(noise_mode,
+                                     delay_mode,
+                                     AttributionConfig()) {}
 
 AttributionStorageDelegateImpl::AttributionStorageDelegateImpl(
     AttributionNoiseMode noise_mode,
     AttributionDelayMode delay_mode,
-    const AttributionConfig& config,
-    std::unique_ptr<AttributionRandomGenerator> rng)
+    const AttributionConfig& config)
     : AttributionStorageDelegate(config),
       noise_mode_(noise_mode),
-      delay_mode_(delay_mode),
-      rng_(std::move(rng)) {
-  DCHECK(rng_);
-
+      delay_mode_(delay_mode) {
   DETACH_FROM_SEQUENCE(sequence_checker_);
 }
 
@@ -95,7 +86,7 @@
       switch (noise_mode_) {
         case AttributionNoiseMode::kDefault:
           return trigger_time + config_.aggregate_limit.min_delay +
-                 rng_->RandDouble() * config_.aggregate_limit.delay_span;
+                 base::RandDouble() * config_.aggregate_limit.delay_span;
         case AttributionNoiseMode::kNone:
           return trigger_time + config_.aggregate_limit.min_delay +
                  config_.aggregate_limit.delay_span;
@@ -138,7 +129,7 @@
 
   switch (noise_mode_) {
     case AttributionNoiseMode::kDefault:
-      rng_->RandomShuffle(reports);
+      base::RandomShuffle(reports.begin(), reports.end());
       break;
     case AttributionNoiseMode::kNone:
       break;
@@ -157,7 +148,7 @@
       DCHECK_GE(randomized_trigger_rate, 0);
       DCHECK_LE(randomized_trigger_rate, 1);
 
-      return rng_->RandDouble() < randomized_trigger_rate
+      return base::RandDouble() < randomized_trigger_rate
                  ? absl::make_optional(GetRandomFakeReports(source))
                  : absl::nullopt;
     }
@@ -178,7 +169,7 @@
           NumReportWindows(source.source_type()));
 
   // Subtract 1 because `AttributionRandomGenerator::RandInt()` is inclusive.
-  const int sequence_index = rng_->RandInt(0, num_combinations - 1);
+  const int sequence_index = base::RandInt(0, num_combinations - 1);
 
   return GetFakeReportsForSequenceIndex(source, sequence_index);
 }
diff --git a/content/browser/attribution_reporting/attribution_storage_delegate_impl.h b/content/browser/attribution_reporting/attribution_storage_delegate_impl.h
index 76096d21..a5697ad 100644
--- a/content/browser/attribution_reporting/attribution_storage_delegate_impl.h
+++ b/content/browser/attribution_reporting/attribution_storage_delegate_impl.h
@@ -16,7 +16,6 @@
 namespace content {
 
 struct AttributionConfig;
-class AttributionRandomGenerator;
 class CommonSourceInfo;
 
 // Implementation of the storage delegate. This class handles assigning
@@ -30,8 +29,7 @@
   static std::unique_ptr<AttributionStorageDelegate> CreateForTesting(
       AttributionNoiseMode noise_mode,
       AttributionDelayMode delay_mode,
-      const AttributionConfig& config,
-      std::unique_ptr<AttributionRandomGenerator> rng);
+      const AttributionConfig& config);
 
   explicit AttributionStorageDelegateImpl(
       AttributionNoiseMode noise_mode = AttributionNoiseMode::kDefault,
@@ -79,16 +77,12 @@
       int random_stars_and_bars_sequence_index) const;
 
  protected:
-  AttributionStorageDelegateImpl(
-      AttributionNoiseMode noise_mode,
-      AttributionDelayMode delay_mode,
-      const AttributionConfig& config,
-      std::unique_ptr<AttributionRandomGenerator> rng);
+  AttributionStorageDelegateImpl(AttributionNoiseMode noise_mode,
+                                 AttributionDelayMode delay_mode,
+                                 const AttributionConfig& config);
 
   const AttributionNoiseMode noise_mode_ GUARDED_BY_CONTEXT(sequence_checker_);
   const AttributionDelayMode delay_mode_ GUARDED_BY_CONTEXT(sequence_checker_);
-  const std::unique_ptr<AttributionRandomGenerator> rng_
-      GUARDED_BY_CONTEXT(sequence_checker_);
 };
 
 }  // namespace content
diff --git a/content/browser/attribution_reporting/attribution_storage_sql.cc b/content/browser/attribution_reporting/attribution_storage_sql.cc
index 5c4c5ed0..5fc1dbe 100644
--- a/content/browser/attribution_reporting/attribution_storage_sql.cc
+++ b/content/browser/attribution_reporting/attribution_storage_sql.cc
@@ -46,6 +46,7 @@
 #include "content/browser/attribution_reporting/attribution_utils.h"
 #include "content/browser/attribution_reporting/common_source_info.h"
 #include "content/browser/attribution_reporting/rate_limit_result.h"
+#include "content/browser/attribution_reporting/sql_queries.h"
 #include "content/browser/attribution_reporting/sql_utils.h"
 #include "content/browser/attribution_reporting/storable_source.h"
 #include "content/browser/attribution_reporting/stored_source.h"
@@ -749,12 +750,8 @@
   // of reports per source_id. Selects the report with lowest priority,
   // and uses the greatest trigger_time to break ties. This favors sending
   // reports for report closer to the source time.
-  static constexpr char kMinPrioritySql[] =
-      "SELECT priority,trigger_time,report_id "
-      "FROM event_level_reports "
-      "WHERE source_id=? AND report_time=?";
-  sql::Statement min_priority_statement(
-      db_->GetCachedStatement(SQL_FROM_HERE, kMinPrioritySql));
+  sql::Statement min_priority_statement(db_->GetCachedStatement(
+      SQL_FROM_HERE, attribution_queries::kMinPrioritySql));
   min_priority_statement.BindInt64(0, *source.source_id());
   min_priority_statement.BindTime(1, report.report_time());
 
@@ -1099,16 +1096,8 @@
   // past their expiry time. The sources are fetched in order so that the
   // first one is the one that will be attributed; the others will be deleted or
   // deactivated, depending on whether they have ever been attributed.
-  static constexpr char kGetMatchingSourcesSql[] =
-      "SELECT source_id,num_attributions,aggregatable_budget_consumed "
-      "FROM sources "
-      "WHERE destination_site=? AND reporting_origin=? "
-      "AND(event_level_active=1 OR aggregatable_active=1)"
-      "AND expiry_time>? "
-      "ORDER BY priority DESC,source_time DESC";
-
-  sql::Statement statement(
-      db_->GetCachedStatement(SQL_FROM_HERE, kGetMatchingSourcesSql));
+  sql::Statement statement(db_->GetCachedStatement(
+      SQL_FROM_HERE, attribution_queries::kGetMatchingSourcesSql));
   statement.BindString(0, net::SchemefulSite(destination_origin).Serialize());
   statement.BindString(1, reporting_origin.Serialize());
   statement.BindTime(2, trigger_time);
@@ -1594,16 +1583,8 @@
 
   // Delete all sources that have no associated reports and are past
   // their expiry time. Optimized by |kImpressionExpiryIndexSql|.
-  static constexpr char kSelectExpiredSourcesSql[] =
-      "SELECT source_id FROM sources "
-      "WHERE expiry_time<=? AND "
-      "source_id NOT IN("
-      "SELECT source_id FROM event_level_reports"
-      ")AND source_id NOT IN("
-      "SELECT source_id FROM aggregatable_report_metadata"
-      ")LIMIT ?";
-  sql::Statement select_expired_statement(
-      db_->GetCachedStatement(SQL_FROM_HERE, kSelectExpiredSourcesSql));
+  sql::Statement select_expired_statement(db_->GetCachedStatement(
+      SQL_FROM_HERE, attribution_queries::kSelectExpiredSourcesSql));
   select_expired_statement.BindTime(0, base::Time::Now());
   select_expired_statement.BindInt(1, kMaxDeletesPerBatch);
   if (!delete_sources_from_paged_select(select_expired_statement)) {
@@ -1614,16 +1595,8 @@
   // inactive. This is done in a separate statement from
   // |kSelectExpiredSourcesSql| so that each query is optimized by an index.
   // Optimized by |kConversionDestinationIndexSql|.
-  static constexpr char kSelectInactiveSourcesSql[] =
-      "SELECT source_id FROM sources "
-      "WHERE event_level_active=0 AND aggregatable_active=0 AND "
-      "source_id NOT IN("
-      "SELECT source_id FROM event_level_reports"
-      ")AND source_id NOT IN("
-      "SELECT source_id FROM aggregatable_report_metadata"
-      ")LIMIT ?";
-  sql::Statement select_inactive_statement(
-      db_->GetCachedStatement(SQL_FROM_HERE, kSelectInactiveSourcesSql));
+  sql::Statement select_inactive_statement(db_->GetCachedStatement(
+      SQL_FROM_HERE, attribution_queries::kSelectInactiveSourcesSql));
   select_inactive_statement.BindInt(0, kMaxDeletesPerBatch);
   return delete_sources_from_paged_select(select_inactive_statement);
 }
@@ -1776,15 +1749,8 @@
   // crrev.com/c/2150071/4/content/browser/conversions/conversion_storage_sql.cc#342
   //
   // TODO(crbug.com/1290377): Look into optimizing origin filter callback.
-  static constexpr char kScanCandidateData[] =
-      "SELECT I.source_origin,I.destination_origin,I.reporting_origin,"
-      "I.source_id,C.report_id "
-      "FROM sources I LEFT JOIN event_level_reports C ON "
-      "C.source_id=I.source_id WHERE"
-      "(I.source_time BETWEEN ?1 AND ?2)OR"
-      "(C.trigger_time BETWEEN ?1 AND ?2)";
-  sql::Statement statement(
-      db_->GetCachedStatement(SQL_FROM_HERE, kScanCandidateData));
+  sql::Statement statement(db_->GetCachedStatement(
+      SQL_FROM_HERE, attribution_queries::kScanCandidateData));
   statement.BindTime(0, delete_begin);
   statement.BindTime(1, delete_end);
 
@@ -1845,10 +1811,8 @@
   // second report in limbo (it was not in the deletion time range).
   // Delete all unattributed reports here to ensure everything is cleaned
   // up.
-  static constexpr char kDeleteVestigialConversionSql[] =
-      "DELETE FROM event_level_reports WHERE source_id=?";
-  sql::Statement delete_vestigial_statement(
-      db_->GetCachedStatement(SQL_FROM_HERE, kDeleteVestigialConversionSql));
+  sql::Statement delete_vestigial_statement(db_->GetCachedStatement(
+      SQL_FROM_HERE, attribution_queries::kDeleteVestigialConversionSql));
   for (StoredSource::Id source_id : source_ids_to_delete) {
     delete_vestigial_statement.Reset(/*clear_bound_vars=*/true);
     delete_vestigial_statement.BindInt64(0, *source_id);
@@ -1952,14 +1916,8 @@
 
 bool AttributionStorageSql::HasCapacityForStoringSource(
     const std::string& serialized_origin) {
-  static constexpr char kCountSourcesSql[] =
-      // clang-format off
-      "SELECT COUNT(*)FROM sources "
-      "WHERE source_origin=? "
-      "AND(event_level_active=1 OR aggregatable_active=1)";  // clang-format on
-
-  sql::Statement statement(
-      db_->GetCachedStatement(SQL_FROM_HERE, kCountSourcesSql));
+  sql::Statement statement(db_->GetCachedStatement(
+      SQL_FROM_HERE, attribution_queries::kCountSourcesSql));
   statement.BindString(0, serialized_origin);
   if (!statement.Step()) {
     return false;
@@ -1977,11 +1935,8 @@
     return ReportAlreadyStoredStatus::kNotStored;
   }
 
-  static constexpr char kCountReportsSql[] =
-      "SELECT COUNT(*)FROM dedup_keys "
-      "WHERE source_id=? AND report_type=? AND dedup_key=?";
-  sql::Statement statement(
-      db_->GetCachedStatement(SQL_FROM_HERE, kCountReportsSql));
+  sql::Statement statement(db_->GetCachedStatement(
+      SQL_FROM_HERE, attribution_queries::kCountReportsSql));
   statement.BindInt64(0, *source_id);
   statement.BindInt(1, SerializeReportType(report_type));
   statement.BindInt64(2, SerializeUint64(*dedup_key));
@@ -2082,10 +2037,8 @@
 absl::optional<std::vector<uint64_t>> AttributionStorageSql::ReadDedupKeys(
     StoredSource::Id source_id,
     AttributionReport::Type report_type) {
-  static constexpr char kDedupKeySql[] =
-      "SELECT dedup_key FROM dedup_keys WHERE source_id=? AND report_type=?";
-  sql::Statement statement(
-      db_->GetCachedStatement(SQL_FROM_HERE, kDedupKeySql));
+  sql::Statement statement(db_->GetCachedStatement(
+      SQL_FROM_HERE, attribution_queries::kDedupKeySql));
   statement.BindInt64(0, *source_id);
   statement.BindInt(1, SerializeReportType(report_type));
 
@@ -2582,15 +2535,8 @@
 
   // TODO(linnan): Considering optimizing SQL query by moving some logic to C++.
   // See the comment in crrev.com/c/3379484 for more information.
-  static constexpr char kScanCandidateData[] =
-      "SELECT I.source_origin,I.destination_origin,I.reporting_origin,"
-      "I.source_id,A.aggregation_id "
-      "FROM sources I LEFT JOIN aggregatable_report_metadata A "
-      "ON A.source_id=I.source_id WHERE"
-      "(I.source_time BETWEEN ?1 AND ?2)OR"
-      "(A.trigger_time BETWEEN ?1 AND ?2)";
-  sql::Statement statement(
-      db_->GetCachedStatement(SQL_FROM_HERE, kScanCandidateData));
+  sql::Statement statement(db_->GetCachedStatement(
+      SQL_FROM_HERE, attribution_queries::kScanCandidateDataAggregatable));
   statement.BindTime(0, delete_begin);
   statement.BindTime(1, delete_end);
 
@@ -2662,12 +2608,8 @@
     return -1;
   }
 
-  static constexpr char kDeleteAggregationsSql[] =
-      "DELETE FROM aggregatable_report_metadata "
-      "WHERE source_id=? "
-      "RETURNING aggregation_id";
-  sql::Statement statement(
-      db_->GetCachedStatement(SQL_FROM_HERE, kDeleteAggregationsSql));
+  sql::Statement statement(db_->GetCachedStatement(
+      SQL_FROM_HERE, attribution_queries::kDeleteAggregationsSql));
 
   int num_aggregatable_reports_deleted = 0;
 
diff --git a/content/browser/attribution_reporting/attribution_storage_sql_query_plans_unittest.cc b/content/browser/attribution_reporting/attribution_storage_sql_query_plans_unittest.cc
new file mode 100644
index 0000000..0336bf9b0
--- /dev/null
+++ b/content/browser/attribution_reporting/attribution_storage_sql_query_plans_unittest.cc
@@ -0,0 +1,138 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "base/files/file_path.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/strings/string_util.h"
+#include "content/browser/attribution_reporting/attribution_storage_sql.h"
+#include "content/browser/attribution_reporting/attribution_test_utils.h"
+#include "content/browser/attribution_reporting/sql_queries.h"
+#include "content/browser/attribution_reporting/sql_query_plan_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace content {
+namespace {
+
+class AttributionSqlQueryPlanTest : public testing::Test {
+ public:
+  AttributionSqlQueryPlanTest() = default;
+
+  void SetUp() override {
+    ASSERT_TRUE(temp_directory_.CreateUniqueTempDir());
+    std::unique_ptr<AttributionStorage> storage =
+        std::make_unique<AttributionStorageSql>(
+            temp_directory_.GetPath(),
+            std::make_unique<ConfigurableStorageDelegate>());
+
+    // Make sure lazy initialization happens by adding a record to the db, but
+    // then ensure the database is closed so the sqlite_dev_shell can read it.
+    storage->StoreSource(SourceBuilder().Build());
+    storage.reset();
+    explainer_ = std::make_unique<SqlQueryPlanExplainer>(
+        temp_directory_.GetPath().Append(FILE_PATH_LITERAL("Conversions")));
+  }
+
+  // Helper method to make tests as readable as possible.
+  SqlQueryPlan GetPlan(
+      std::string query,
+      absl::optional<SqlFullScanReason> reason = absl::nullopt) {
+    auto plan = explainer_->GetPlan(std::move(query), reason);
+    EXPECT_TRUE(plan.has_value());
+    return *plan;
+  }
+
+ protected:
+  base::ScopedTempDir temp_directory_;
+  std::unique_ptr<SqlQueryPlanExplainer> explainer_;
+};
+
+TEST_F(AttributionSqlQueryPlanTest, kMinPrioritySql) {
+  SqlQueryPlan plan = GetPlan(attribution_queries::kMinPrioritySql);
+  auto matcher = SqlIndexMatcher("event_level_reports_by_source_id");
+  EXPECT_TRUE(plan.UsesIndex(matcher)) << plan;
+}
+
+TEST_F(AttributionSqlQueryPlanTest, kGetMatchingSourcesSql) {
+  SqlQueryPlan plan = GetPlan(attribution_queries::kGetMatchingSourcesSql);
+  auto matcher = SqlIndexMatcher("sources_by_expiry_time");
+  EXPECT_TRUE(plan.UsesIndex(matcher)) << plan;
+}
+
+TEST_F(AttributionSqlQueryPlanTest, kSelectExpiredSourcesSql) {
+  SqlQueryPlan plan = GetPlan(attribution_queries::kSelectExpiredSourcesSql);
+  EXPECT_TRUE(plan.UsesIndex(SqlIndexMatcher("sources_by_expiry_time")
+                                 .set_type(SqlIndexMatcher::Type::kCovering)))
+      << plan;
+  EXPECT_TRUE(
+      plan.UsesIndex(SqlIndexMatcher("event_level_reports_by_source_id")))
+      << plan;
+  EXPECT_TRUE(plan.UsesIndex(SqlIndexMatcher("aggregate_source_id_idx")))
+      << plan;
+}
+
+TEST_F(AttributionSqlQueryPlanTest, kSelectInactiveSourcesSql) {
+  SqlQueryPlan plan = GetPlan(attribution_queries::kSelectInactiveSourcesSql);
+  EXPECT_TRUE(plan.UsesIndex(
+      SqlIndexMatcher("sources_by_active_destination_site_reporting_origin")
+          .set_type(SqlIndexMatcher::Type::kCovering)
+          .set_columns({"event_level_active", "aggregatable_active"})))
+      << plan;
+  EXPECT_TRUE(
+      plan.UsesIndex(SqlIndexMatcher("event_level_reports_by_source_id")))
+      << plan;
+  EXPECT_TRUE(plan.UsesIndex(SqlIndexMatcher("aggregate_source_id_idx")))
+      << plan;
+}
+
+TEST_F(AttributionSqlQueryPlanTest, kScanCandidateData) {
+  SqlQueryPlan plan = GetPlan(attribution_queries::kScanCandidateData,
+                              SqlFullScanReason::kNotOptimized);
+  EXPECT_TRUE(
+      plan.UsesIndex(SqlIndexMatcher("event_level_reports_by_source_id")))
+      << plan;
+}
+
+TEST_F(AttributionSqlQueryPlanTest, kDeleteVestigialConversionSql) {
+  SqlQueryPlan plan =
+      GetPlan(attribution_queries::kDeleteVestigialConversionSql);
+  EXPECT_TRUE(
+      plan.UsesIndex(SqlIndexMatcher("event_level_reports_by_source_id")))
+      << plan;
+}
+
+TEST_F(AttributionSqlQueryPlanTest, kCountSourcesSql) {
+  SqlQueryPlan plan = GetPlan(attribution_queries::kCountSourcesSql);
+  EXPECT_TRUE(
+      plan.UsesIndex(SqlIndexMatcher("active_sources_by_source_origin")))
+      << plan;
+}
+TEST_F(AttributionSqlQueryPlanTest, kDedupKeySql) {
+  SqlQueryPlan plan = GetPlan(attribution_queries::kDedupKeySql);
+  EXPECT_TRUE(plan.UsesIndex(
+      SqlIndexMatcher().set_type(SqlIndexMatcher::Type::kPrimaryKey)))
+      << plan;
+}
+
+TEST_F(AttributionSqlQueryPlanTest, kScanCandidateDataAggregatable) {
+  SqlQueryPlan plan =
+      GetPlan(attribution_queries::kScanCandidateDataAggregatable,
+              SqlFullScanReason::kNotOptimized);
+  EXPECT_TRUE(plan.UsesIndex(SqlIndexMatcher("aggregate_source_id_idx")))
+      << plan;
+}
+
+TEST_F(AttributionSqlQueryPlanTest, kDeleteAggregationsSql) {
+  SqlQueryPlan plan = GetPlan(attribution_queries::kDeleteAggregationsSql);
+  EXPECT_TRUE(plan.UsesIndex(SqlIndexMatcher("aggregate_source_id_idx")
+                                 .set_type(SqlIndexMatcher::Type::kCovering)))
+      << plan;
+}
+
+}  // namespace
+}  // namespace content
diff --git a/content/browser/attribution_reporting/sql_queries.h b/content/browser/attribution_reporting/sql_queries.h
new file mode 100644
index 0000000..04099a3
--- /dev/null
+++ b/content/browser/attribution_reporting/sql_queries.h
@@ -0,0 +1,79 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_ATTRIBUTION_REPORTING_SQL_QUERIES_H_
+#define CONTENT_BROWSER_ATTRIBUTION_REPORTING_SQL_QUERIES_H_
+
+namespace content::attribution_queries {
+
+inline constexpr const char kMinPrioritySql[] =
+    "SELECT priority,trigger_time,report_id "
+    "FROM event_level_reports "
+    "WHERE source_id=? AND report_time=?";
+
+inline constexpr const char kGetMatchingSourcesSql[] =
+    "SELECT source_id,num_attributions,aggregatable_budget_consumed "
+    "FROM sources "
+    "WHERE destination_site=? AND reporting_origin=? "
+    "AND(event_level_active=1 OR aggregatable_active=1)"
+    "AND expiry_time>? "
+    "ORDER BY priority DESC,source_time DESC";
+
+inline constexpr const char kSelectExpiredSourcesSql[] =
+    "SELECT source_id FROM sources "
+    "WHERE expiry_time<=? AND "
+    "source_id NOT IN("
+    "SELECT source_id FROM event_level_reports"
+    ")AND source_id NOT IN("
+    "SELECT source_id FROM aggregatable_report_metadata"
+    ")LIMIT ?";
+
+inline constexpr const char kSelectInactiveSourcesSql[] =
+    "SELECT source_id FROM sources "
+    "WHERE event_level_active=0 AND aggregatable_active=0 AND "
+    "source_id NOT IN("
+    "SELECT source_id FROM event_level_reports"
+    ")AND source_id NOT IN("
+    "SELECT source_id FROM aggregatable_report_metadata"
+    ")LIMIT ?";
+
+inline constexpr const char kScanCandidateData[] =
+    "SELECT I.source_origin,I.destination_origin,I.reporting_origin,"
+    "I.source_id,C.report_id "
+    "FROM sources I LEFT JOIN event_level_reports C ON "
+    "C.source_id=I.source_id WHERE"
+    "(I.source_time BETWEEN ?1 AND ?2)OR"
+    "(C.trigger_time BETWEEN ?1 AND ?2)";
+
+inline constexpr const char kDeleteVestigialConversionSql[] =
+    "DELETE FROM event_level_reports WHERE source_id=?";
+
+inline constexpr const char kCountSourcesSql[] =
+    "SELECT COUNT(*)FROM sources "
+    "WHERE source_origin=? "
+    "AND(event_level_active=1 OR aggregatable_active=1)";
+
+inline constexpr const char kCountReportsSql[] =
+    "SELECT COUNT(*)FROM dedup_keys "
+    "WHERE source_id=? AND report_type=? AND dedup_key=?";
+
+inline constexpr const char kDedupKeySql[] =
+    "SELECT dedup_key FROM dedup_keys WHERE source_id=? AND report_type=?";
+
+inline constexpr const char kScanCandidateDataAggregatable[] =
+    "SELECT I.source_origin,I.destination_origin,I.reporting_origin,"
+    "I.source_id,A.aggregation_id "
+    "FROM sources I LEFT JOIN aggregatable_report_metadata A "
+    "ON A.source_id=I.source_id WHERE"
+    "(I.source_time BETWEEN ?1 AND ?2)OR"
+    "(A.trigger_time BETWEEN ?1 AND ?2)";
+
+inline constexpr const char kDeleteAggregationsSql[] =
+    "DELETE FROM aggregatable_report_metadata "
+    "WHERE source_id=? "
+    "RETURNING aggregation_id";
+
+}  // namespace content::attribution_queries
+
+#endif  // CONTENT_BROWSER_ATTRIBUTION_REPORTING_SQL_QUERIES_H_
diff --git a/content/browser/attribution_reporting/sql_query_plan_test_util.cc b/content/browser/attribution_reporting/sql_query_plan_test_util.cc
new file mode 100644
index 0000000..c255ccf4
--- /dev/null
+++ b/content/browser/attribution_reporting/sql_query_plan_test_util.cc
@@ -0,0 +1,134 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/attribution_reporting/sql_query_plan_test_util.h"
+
+#include <utility>
+
+#include "base/check.h"
+#include "base/command_line.h"
+#include "base/containers/contains.h"
+#include "base/files/file_util.h"
+#include "base/path_service.h"
+#include "base/process/launch.h"
+#include "base/process/process.h"
+#include "base/ranges/algorithm.h"
+#include "base/strings/strcat.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/string_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+namespace {
+
+base::FilePath GetExecPath(base::StringPiece name) {
+  base::FilePath path;
+  base::PathService::Get(base::DIR_EXE, &path);
+  return path.AppendASCII(name);
+}
+
+}  // namespace
+
+SqlIndexMatcher::SqlIndexMatcher() = default;
+SqlIndexMatcher::SqlIndexMatcher(std::string name) : name_(std::move(name)) {}
+SqlIndexMatcher::~SqlIndexMatcher() = default;
+
+SqlIndexMatcher::SqlIndexMatcher(const SqlIndexMatcher&) = default;
+SqlIndexMatcher& SqlIndexMatcher::operator=(const SqlIndexMatcher&) = default;
+
+SqlQueryPlan::SqlQueryPlan(std::string query, std::string plan)
+    : query_(std::move(query)), plan_(std::move(plan)) {}
+
+SqlQueryPlan::~SqlQueryPlan() = default;
+
+bool SqlQueryPlan::UsesIndex(const SqlIndexMatcher& matcher) const {
+  base::StringPiece plan_piece(plan_);
+
+  size_t start_pos = matcher.FindIndexStart(plan_piece);
+  if (start_pos == std::string::npos) {
+    return false;
+  }
+
+  size_t end_pos = plan_piece.find("\n", start_pos);
+
+  base::StringPiece index_text =
+      plan_piece.substr(start_pos, end_pos - start_pos);
+
+  return base::ranges::all_of(matcher.columns(),
+                              [index_text](const std::string& col) {
+                                return base::Contains(index_text, col);
+                              });
+}
+
+bool SqlQueryPlan::HasFullTableScan() const {
+  return base::Contains(plan_, "SCAN");
+}
+
+size_t SqlIndexMatcher::FindIndexStart(base::StringPiece plan) const {
+  std::string covering_prefix = base::StrCat({"USING COVERING INDEX ", name()});
+  std::string noncovering_prefix = base::StrCat({"USING INDEX ", name()});
+  std::string primary_prefix = "USING PRIMARY KEY ";
+  switch (type()) {
+    case SqlIndexMatcher::Type::kCovering:
+      return plan.find(covering_prefix);
+    case SqlIndexMatcher::Type::kPrimaryKey:
+      DCHECK(name().empty());
+      return plan.find(primary_prefix);
+    case SqlIndexMatcher::Type::kAny:
+      for (const base::StringPiece prefix :
+           {covering_prefix, noncovering_prefix, primary_prefix}) {
+        size_t pos = plan.find(prefix);
+        if (pos != std::string::npos) {
+          return pos;
+        }
+      }
+      return std::string::npos;
+  }
+}
+
+std::ostream& operator<<(std::ostream& out, const SqlQueryPlan& plan) {
+  return out << plan.query_ << "\n" << plan.plan_;
+}
+
+SqlQueryPlanExplainer::SqlQueryPlanExplainer(base::FilePath db_path)
+    : db_path_(std::move(db_path)),
+      shell_path_(GetExecPath("sqlite_dev_shell")) {}
+
+SqlQueryPlanExplainer::~SqlQueryPlanExplainer() = default;
+
+absl::optional<SqlQueryPlan> SqlQueryPlanExplainer::GetPlan(
+    std::string query,
+    absl::optional<SqlFullScanReason> full_scan_reason) {
+  base::CommandLine command_line(shell_path_);
+  command_line.AppendArgPath(db_path_);
+
+  std::string explain_query = base::StrCat({"EXPLAIN QUERY PLAN ", query});
+  command_line.AppendArg(explain_query);
+
+  std::string output;
+  if (!base::GetAppOutputAndError(command_line, &output)) {
+    return absl::nullopt;
+  }
+
+  if (!base::StartsWith(output, "QUERY PLAN")) {
+    return absl::nullopt;
+  }
+
+  SqlQueryPlan plan(std::move(query), std::move(output));
+
+  if (full_scan_reason.has_value()) {
+    EXPECT_TRUE(plan.HasFullTableScan())
+        << "Plan has out of date SqlFullScanReason. No full scan was found:\n"
+        << plan;
+  } else {
+    EXPECT_FALSE(plan.HasFullTableScan())
+        << "Plan has a full table scan, which must be "
+           "annotated with a SqlFullScanReason:\n"
+        << plan;
+  }
+  return plan;
+}
+
+}  // namespace content
diff --git a/content/browser/attribution_reporting/sql_query_plan_test_util.h b/content/browser/attribution_reporting/sql_query_plan_test_util.h
new file mode 100644
index 0000000..c68c908
--- /dev/null
+++ b/content/browser/attribution_reporting/sql_query_plan_test_util.h
@@ -0,0 +1,127 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_ATTRIBUTION_REPORTING_SQL_QUERY_PLAN_TEST_UTIL_H_
+#define CONTENT_BROWSER_ATTRIBUTION_REPORTING_SQL_QUERY_PLAN_TEST_UTIL_H_
+
+#include <ostream>
+#include <string>
+#include <vector>
+
+#include "base/files/file_path.h"
+#include "base/strings/string_piece_forward.h"
+
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace content {
+
+// TODO(crbug.com/1407007): Move these utilities to //sql once they are trialed
+// in the attribution_reporting directory.
+//
+// Class which specifies how to match an index in a query plan.
+class SqlIndexMatcher {
+ public:
+  // Only matches an index with the given name. Note, for primary key indices,
+  // this is unused, so the constructor without the name field should be used.
+  explicit SqlIndexMatcher(std::string name);
+  SqlIndexMatcher();
+  ~SqlIndexMatcher();
+
+  SqlIndexMatcher(const SqlIndexMatcher&);
+  SqlIndexMatcher& operator=(const SqlIndexMatcher& o);
+
+  // Every sqlite index includes a list of indexed columns. However, some query
+  // plans will only use a subset of the columns in the index. This matcher is
+  // designed to enforce that a given subset of columns are actually used by the
+  // query planner. Note that this list doesn't have to be exhaustive, and
+  // plans that use a superset of columns than ones listed in `columns` will
+  // still match.
+  SqlIndexMatcher& set_columns(std::vector<std::string> columns) {
+    columns_ = std::move(columns);
+    return *this;
+  }
+
+  // Specifies the type of index that we should match with. Note this also
+  // covers primary keys which are implemented as indexes in sqlite.
+  enum class Type {
+    kAny,         // USING INDEX, or any of the other options with match
+    kCovering,    // USING COVERING INDEX
+    kPrimaryKey,  // USING PRIMARY KEY
+  };
+  SqlIndexMatcher& set_type(Type type) {
+    type_ = type;
+    return *this;
+  }
+
+  const std::string& name() const { return name_; }
+  const std::vector<std::string>& columns() const { return columns_; }
+  Type type() const { return type_; }
+
+  size_t FindIndexStart(base::StringPiece plan) const;
+
+ private:
+  std::string name_;
+  std::vector<std::string> columns_;
+  Type type_ = Type::kAny;
+};
+
+// This class wraps a returned sqlite query plan, as returned from EXPLAIN QUERY
+// PLAN, and allows making various checks on its properties.
+class SqlQueryPlan {
+ public:
+  SqlQueryPlan(std::string query, std::string plan);
+  ~SqlQueryPlan();
+
+  // Returns true if the query plan uses the index specified by `index`.
+  [[nodiscard]] bool UsesIndex(const SqlIndexMatcher& matcher) const;
+
+  // Returns true if the query plan does any full table scan, i.e. it includes a
+  // SCAN directive.
+  [[nodiscard]] bool HasFullTableScan() const;
+
+ private:
+  friend std::ostream& operator<<(std::ostream& out, const SqlQueryPlan& plan);
+
+  const std::string query_;
+  const std::string plan_;
+};
+
+// Only for diagnostic messages, not for test expectations, as the underlying
+// query plan format is fragile and should not be relied upon.
+std::ostream& operator<<(std::ostream& out, const SqlQueryPlan& plan);
+
+// Enum explaining why a full scan on a query is needed. For use when annotating
+// tests which use queries that perform a full table scan.
+enum class SqlFullScanReason {
+  // The full table scan is intentional, the query has to perform one.
+  kIntentional,
+  // The full table scan is not intentional and is only present because the
+  // query has not been optimized.
+  kNotOptimized,
+};
+
+// This class runs the sqlite_dev_shell to call EXPLAIN QUERY PLAN on provided
+// queries, in the context of the passed in `db_path`.
+class SqlQueryPlanExplainer {
+ public:
+  explicit SqlQueryPlanExplainer(base::FilePath db_path);
+
+  ~SqlQueryPlanExplainer();
+
+  // Returns the query plan for a given query. Returns nullopt on error. Makes
+  // test expectations based on the SqlFullScanReason, which enforces by default
+  // that query plans should not perform full table scans and must be annotated
+  // when they do.
+  absl::optional<SqlQueryPlan> GetPlan(
+      std::string query,
+      absl::optional<SqlFullScanReason> full_scan_reason = absl::nullopt);
+
+ private:
+  const base::FilePath db_path_;
+  const base::FilePath shell_path_;
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_ATTRIBUTION_REPORTING_SQL_QUERY_PLAN_TEST_UTIL_H_
diff --git a/content/browser/back_forward_cache_features_browsertest.cc b/content/browser/back_forward_cache_features_browsertest.cc
index 4a9e73b..bf4d3b5 100644
--- a/content/browser/back_forward_cache_features_browsertest.cc
+++ b/content/browser/back_forward_cache_features_browsertest.cc
@@ -2611,6 +2611,75 @@
   }
 }
 
+IN_PROC_BROWSER_TEST_P(BackForwardCacheBrowserTestWithFlagForIndexedDB,
+                       EvictCacheIfPageBlocksNewTransaction) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  Shell* tab_holding_locks = shell();
+  Shell* tab_acquiring_locks = CreateBrowser();
+
+  // 1) Navigate the tab holding locks to A and use IndexedDB, it also register
+  // a event on pagehide to run tasks that never ends to keep the IndexedDB
+  // transaction locks.
+  ASSERT_TRUE(NavigateToURL(
+      tab_holding_locks,
+      embedded_test_server()->GetURL(
+          "a.com", "/back_forward_cache/page_with_indexedDB.html")));
+  RenderFrameHostImplWrapper rfh_a(current_frame_host());
+
+  content::DOMMessageQueue queue_holding_locks(
+      tab_holding_locks->web_contents());
+  std::string message_holding_locks;
+  ASSERT_TRUE(ExecJs(tab_holding_locks, "setupIndexedDBConnection()"));
+  ASSERT_TRUE(
+      ExecJs(tab_holding_locks, "registerPagehideToStartTransaction()"));
+
+  // 2) Navigate the tab holding locks away.
+  ASSERT_TRUE(NavigateToURL(tab_holding_locks, embedded_test_server()->GetURL(
+                                                   "b.com", "/title1.html")));
+
+  // 3) After confirming the transaction has been created from the tab holding
+  // locks, navigate the tab acquiring locks to A that tries to acquire the same
+  // lock.
+  ASSERT_TRUE(queue_holding_locks.WaitForMessage(&message_holding_locks));
+  ASSERT_EQ("\"transaction_created\"", message_holding_locks);
+  ASSERT_TRUE(NavigateToURL(
+      tab_acquiring_locks,
+      embedded_test_server()->GetURL(
+          "a.com", "/back_forward_cache/page_with_indexedDB.html")));
+
+  content::DOMMessageQueue queue_acquiring_locks(
+      tab_acquiring_locks->web_contents());
+  std::string message_acquiring_locks;
+  ASSERT_TRUE(ExecJs(tab_acquiring_locks, "setupIndexedDBConnection()"));
+  ASSERT_TRUE(ExecJs(tab_acquiring_locks, "startIndexedDBTransaction()"));
+
+  // 4) After confirming that the transaction from the tab acquiring locks is
+  // completed (which should evict the other tab if it's in BFCache), navigate
+  // the tab holding locks back to the page with IndexedDB.
+  ASSERT_TRUE(queue_acquiring_locks.WaitForMessage(&message_acquiring_locks));
+  ASSERT_EQ("\"transaction_completed\"", message_acquiring_locks);
+  if (ShouldAllowPageWithIndexedDBTransactionInBFCache()) {
+    // If the flag that enables a page with IndexedDB features to enter BFCache
+    // is toggled on, the page should be evicted by disallowing activation.
+    ASSERT_TRUE(rfh_a.WaitUntilRenderFrameDeleted());
+    ASSERT_TRUE(HistoryGoBack(tab_holding_locks->web_contents()));
+    ExpectNotRestored(
+        {NotRestoredReason::kIgnoreEventAndEvict}, {}, {}, {},
+        {DisallowActivationReasonId::kIndexedDBTransactionIsBlockingOthers},
+        FROM_HERE);
+  } else {
+    // If the flag is not toggled on, the page will not be eligible for BFCache
+    // because of the registered feature.
+    ASSERT_TRUE(rfh_a.WaitUntilRenderFrameDeleted());
+    ASSERT_TRUE(HistoryGoBack(tab_holding_locks->web_contents()));
+    ExpectNotRestored({NotRestoredReason::kBlocklistedFeatures},
+                      {blink::scheduler::WebSchedulerTrackedFeature::
+                           kOutstandingIndexedDBTransaction},
+                      {}, {}, {}, FROM_HERE);
+  }
+}
+
 IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
                        DoesNotCacheIfBroadcastChannelStillOpen) {
   ASSERT_TRUE(CreateHttpsServer()->Start());
@@ -3071,7 +3140,7 @@
   Shell* tab_to_execute_service_worker = shell();
   Shell* tab_to_be_bfcached = CreateBrowser();
 
-  // Observe the new WebContents to trace the navigtion ID.
+  // Observe the new WebContents to trace the navigation ID.
   WebContentsObserver::Observe(tab_to_be_bfcached->web_contents());
 
   // 1) Navigate to A in |tab_to_execute_service_worker|.
diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc
index 952f637..ee7fa2fe 100644
--- a/content/browser/indexed_db/indexed_db_database.cc
+++ b/content/browser/indexed_db/indexed_db_database.cc
@@ -7,7 +7,6 @@
 #include <math.h>
 #include <algorithm>
 #include <cstddef>
-#include <set>
 #include <utility>
 
 #include "base/auto_reset.h"
@@ -197,15 +196,61 @@
   return lock_requests;
 }
 
+void IndexedDBDatabase::RequireBlockingTransactionClientsToBeActive(
+    IndexedDBTransaction* current_transaction,
+    std::vector<PartitionedLockManager::PartitionedLockRequest>&
+        lock_requests) {
+  std::vector<PartitionedLockId> blocked_lock_ids =
+      lock_manager_->GetUnacquirableLocks(lock_requests);
+
+  if (blocked_lock_ids.empty()) {
+    return;
+  }
+
+  for (IndexedDBConnection* connection : connections_) {
+    bool should_require_connection_to_be_active = false;
+    for (const auto& [existing_transaction_id, existing_transaction] :
+         connection->transactions()) {
+      if (connection->id() == current_transaction->connection()->id() &&
+          existing_transaction_id == current_transaction->id()) {
+        // This is the current transaction itself, we skip the check.
+        continue;
+      }
+      for (PartitionedLockId blocked_lock_id : blocked_lock_ids) {
+        if (existing_transaction->lock_ids().contains(blocked_lock_id)) {
+          should_require_connection_to_be_active = true;
+          break;
+        }
+      }
+    }
+    if (should_require_connection_to_be_active) {
+      connection->RequireClientToBeActive(
+          storage::mojom::DisallowClientActivationReason::
+              kTransactionIsBlockingOthers);
+    }
+  }
+}
+
 void IndexedDBDatabase::RegisterAndScheduleTransaction(
     IndexedDBTransaction* transaction) {
   TRACE_EVENT1("IndexedDB", "IndexedDBDatabase::RegisterAndScheduleTransaction",
                "txn.id", transaction->id());
   std::vector<PartitionedLockManager::PartitionedLockRequest> lock_requests =
       BuildLockRequestsFromTransaction(transaction);
+
+  if (base::FeatureList::IsEnabled(
+          blink::features::kAllowPageWithIDBTransactionInBFCache)) {
+    CHECK(base::FeatureList::IsEnabled(
+        blink::features::kAllowPageWithIDBConnectionInBFCache))
+        << "kAllowPageWithIDBTransactionInBFCache should only be turned on "
+           "when kAllowPageWithIDBConnectionInBFCache is on.";
+
+    RequireBlockingTransactionClientsToBeActive(transaction, lock_requests);
+  }
+
   lock_manager_->AcquireLocks(
       std::move(lock_requests),
-      transaction->mutable_locks_receiver()->weak_factory.GetWeakPtr(),
+      transaction->mutable_locks_receiver()->AsWeakPtr(),
       base::BindOnce(&IndexedDBTransaction::Start, transaction->AsWeakPtr()));
 }
 
diff --git a/content/browser/indexed_db/indexed_db_database.h b/content/browser/indexed_db/indexed_db_database.h
index 1ed3288..7449c20 100644
--- a/content/browser/indexed_db/indexed_db_database.h
+++ b/content/browser/indexed_db/indexed_db_database.h
@@ -381,6 +381,13 @@
   std::vector<PartitionedLockManager::PartitionedLockRequest>
   BuildLockRequestsFromTransaction(IndexedDBTransaction* transaction) const;
 
+  // Find the transactions that block `current_transaction` from acquiring the
+  // locks, and ensure that the clients with blocking transactions are active.
+  void RequireBlockingTransactionClientsToBeActive(
+      IndexedDBTransaction* current_transaction,
+      std::vector<PartitionedLockManager::PartitionedLockRequest>&
+          lock_requests);
+
   // Safe because the IndexedDBBackingStore is owned by the same object which
   // owns us, the IndexedDBPerBucketFactory.
   raw_ptr<IndexedDBBackingStore> backing_store_;
diff --git a/content/browser/preloading/prefetch/prefetch_document_manager_unittest.cc b/content/browser/preloading/prefetch/prefetch_document_manager_unittest.cc
index 4c782b27..9a40b1d 100644
--- a/content/browser/preloading/prefetch/prefetch_document_manager_unittest.cc
+++ b/content/browser/preloading/prefetch/prefetch_document_manager_unittest.cc
@@ -310,7 +310,7 @@
   candidate6->requires_anonymous_client_ip_when_cross_origin = true;
   candidate6->url = GetCrossOriginUrl("/candidate6.html");
   candidate6->referrer = blink::mojom::Referrer::New();
-  candidate6->eagerness = blink::mojom::SpeculationEagerness::kDefault;
+  candidate6->eagerness = blink::mojom::SpeculationEagerness::kConservative;
   candidates.push_back(std::move(candidate6));
 
   // Process the candidates with the |PrefetchDocumentManager| for the current
@@ -344,7 +344,7 @@
   EXPECT_EQ(prefetch_urls[3]->GetPrefetchType(),
             PrefetchType(/*use_isolated_network_context=*/true,
                          /*use_prefetch_proxy=*/true,
-                         blink::mojom::SpeculationEagerness::kDefault));
+                         blink::mojom::SpeculationEagerness::kConservative));
 
   // Check that the only remaining entries in candidates are those that
   // shouldn't be prefetched by |PrefetchService|.
diff --git a/content/browser/preloading/prefetch/prefetch_params.cc b/content/browser/preloading/prefetch/prefetch_params.cc
index ccf7dae..c17f815 100644
--- a/content/browser/preloading/prefetch/prefetch_params.cc
+++ b/content/browser/preloading/prefetch/prefetch_params.cc
@@ -230,10 +230,14 @@
       return base::GetFieldTrialParamByFeatureAsBool(
           features::kPrefetchUseContentRefactor,
           "block_until_head_eager_prefetch", false);
-    case blink::mojom::SpeculationEagerness::kDefault:
+    case blink::mojom::SpeculationEagerness::kModerate:
       return base::GetFieldTrialParamByFeatureAsBool(
           features::kPrefetchUseContentRefactor,
-          "block_until_head_default_prefetch", true);
+          "block_until_head_moderate_prefetch", true);
+    case blink::mojom::SpeculationEagerness::kConservative:
+      return base::GetFieldTrialParamByFeatureAsBool(
+          features::kPrefetchUseContentRefactor,
+          "block_until_head_conservative_prefetch", true);
   }
 }
 
diff --git a/content/browser/preloading/prefetch/prefetch_service_unittest.cc b/content/browser/preloading/prefetch/prefetch_service_unittest.cc
index 9df1e737..13abd13 100644
--- a/content/browser/preloading/prefetch/prefetch_service_unittest.cc
+++ b/content/browser/preloading/prefetch/prefetch_service_unittest.cc
@@ -3214,7 +3214,8 @@
           {{"ineligible_decoy_request_probability", "0"},
            {"prefetch_container_lifetime_s", "-1"},
            {"block_until_head_eager_prefetch", "false"},
-           {"block_until_head_default_prefetch", "false"}}}},
+           {"block_until_head_moderate_prefetch", "false"},
+           {"block_until_head_conservative_prefetch", "false"}}}},
         {network::features::kPrefetchNoVarySearch});
   }
 };
@@ -3283,7 +3284,9 @@
                        PreloadingFailureReason::kUnspecified);
 }
 
-class PrefetchServiceAlwaysBlockUntilHeadTest : public PrefetchServiceTest {
+class PrefetchServiceAlwaysBlockUntilHeadTest
+    : public PrefetchServiceTest,
+      public ::testing::WithParamInterface<blink::mojom::SpeculationEagerness> {
  public:
   void InitScopedFeatureList() override {
     scoped_feature_list_.InitWithFeaturesAndParameters(
@@ -3291,7 +3294,8 @@
           {{"ineligible_decoy_request_probability", "0"},
            {"prefetch_container_lifetime_s", "-1"},
            {"block_until_head_eager_prefetch", "true"},
-           {"block_until_head_default_prefetch", "true"}}}},
+           {"block_until_head_moderate_prefetch", "true"},
+           {"block_until_head_conservative_prefetch", "true"}}}},
         {network::features::kPrefetchNoVarySearch});
   }
 };
@@ -3302,7 +3306,7 @@
 #else
 #define MAYBE_BlockUntilHeadReceived BlockUntilHeadReceived
 #endif
-TEST_F(PrefetchServiceAlwaysBlockUntilHeadTest, MAYBE_BlockUntilHeadReceived) {
+TEST_P(PrefetchServiceAlwaysBlockUntilHeadTest, MAYBE_BlockUntilHeadReceived) {
   base::HistogramTester histogram_tester;
 
   MakePrefetchService(
@@ -3311,8 +3315,7 @@
   MakePrefetchOnMainFrame(
       GURL("https://example.com"),
       PrefetchType(/*use_isolated_network_context=*/true,
-                   /*use_prefetch_proxy=*/true,
-                   blink::mojom::SpeculationEagerness::kDefault));
+                   /*use_prefetch_proxy=*/true, GetParam()));
   base::RunLoop().RunUntilIdle();
 
   VerifyCommonRequestState(GURL("https://example.com"),
@@ -3396,5 +3399,11 @@
                        PreloadingFailureReason::kUnspecified);
 }
 
+INSTANTIATE_TEST_SUITE_P(
+    ParametrizedTests,
+    PrefetchServiceAlwaysBlockUntilHeadTest,
+    testing::Values(blink::mojom::SpeculationEagerness::kModerate,
+                    blink::mojom::SpeculationEagerness::kConservative));
+
 }  // namespace
 }  // namespace content
diff --git a/content/browser/preloading/prefetch/prefetch_type_unittest.cc b/content/browser/preloading/prefetch/prefetch_type_unittest.cc
index 38a8f8da..fc124e0 100644
--- a/content/browser/preloading/prefetch/prefetch_type_unittest.cc
+++ b/content/browser/preloading/prefetch/prefetch_type_unittest.cc
@@ -18,9 +18,10 @@
   PrefetchType prefetch_type2(/*use_isolated_network_context=*/true,
                               /*use_prefetch_proxy=*/false,
                               blink::mojom::SpeculationEagerness::kEager);
-  PrefetchType prefetch_type3(/*use_isolated_network_context=*/false,
-                              /*use_prefetch_proxy=*/false,
-                              blink::mojom::SpeculationEagerness::kDefault);
+  PrefetchType prefetch_type3(
+      /*use_isolated_network_context=*/false,
+      /*use_prefetch_proxy=*/false,
+      blink::mojom::SpeculationEagerness::kConservative);
 
   EXPECT_TRUE(prefetch_type1.IsIsolatedNetworkContextRequired());
   EXPECT_TRUE(prefetch_type1.IsProxyRequired());
@@ -35,7 +36,7 @@
   EXPECT_FALSE(prefetch_type3.IsIsolatedNetworkContextRequired());
   EXPECT_FALSE(prefetch_type3.IsProxyRequired());
   EXPECT_EQ(prefetch_type3.GetEagerness(),
-            blink::mojom::SpeculationEagerness::kDefault);
+            blink::mojom::SpeculationEagerness::kConservative);
 }
 
 TEST_F(PrefetchTypeTest, ComparePrefetchTypes) {
@@ -51,9 +52,10 @@
   PrefetchType prefetch_type4(/*use_isolated_network_context=*/false,
                               /*use_prefetch_proxy=*/false,
                               blink::mojom::SpeculationEagerness::kEager);
-  PrefetchType prefetch_type5(/*use_isolated_network_context=*/true,
-                              /*use_prefetch_proxy=*/true,
-                              blink::mojom::SpeculationEagerness::kDefault);
+  PrefetchType prefetch_type5(
+      /*use_isolated_network_context=*/true,
+      /*use_prefetch_proxy=*/true,
+      blink::mojom::SpeculationEagerness::kConservative);
 
   // Explicitly test the == and != operators for |PrefetchType|.
   EXPECT_TRUE(prefetch_type1 == prefetch_type1);
diff --git a/content/browser/preloading/preloading_decider_unittest.cc b/content/browser/preloading/preloading_decider_unittest.cc
index 19570cda..7645907 100644
--- a/content/browser/preloading/preloading_decider_unittest.cc
+++ b/content/browser/preloading/preloading_decider_unittest.cc
@@ -191,13 +191,13 @@
                          blink::mojom::SpeculationEagerness>>
       test_cases{{true, GetCrossOriginUrl("/candidate1.html"),
                   blink::mojom::SpeculationAction::kPrefetch,
-                  blink::mojom::SpeculationEagerness::kDefault},
+                  blink::mojom::SpeculationEagerness::kConservative},
                  {false, GetCrossOriginUrl("/candidate2.html"),
                   blink::mojom::SpeculationAction::kPrefetch,
                   blink::mojom::SpeculationEagerness::kEager},
                  {true, GetCrossOriginUrl("/candidate1.html"),
                   blink::mojom::SpeculationAction::kPrerender,
-                  blink::mojom::SpeculationEagerness::kDefault},
+                  blink::mojom::SpeculationEagerness::kConservative},
                  {false, GetCrossOriginUrl("/candidate2.html"),
                   blink::mojom::SpeculationAction::kPrerender,
                   blink::mojom::SpeculationEagerness::kEager}};
@@ -242,7 +242,7 @@
   candidate1->requires_anonymous_client_ip_when_cross_origin = true;
   candidate1->url = GetCrossOriginUrl("/candidate1.html");
   candidate1->referrer = blink::mojom::Referrer::New();
-  candidate1->eagerness = blink::mojom::SpeculationEagerness::kDefault;
+  candidate1->eagerness = blink::mojom::SpeculationEagerness::kConservative;
   candidates.push_back(std::move(candidate1));
 
   preloading_decider->UpdateSpeculationCandidates(candidates);
@@ -297,10 +297,10 @@
 
   candidates.push_back(CreateCandidate(
       blink::mojom::SpeculationAction::kPrerender, "/candidate1.html",
-      blink::mojom::SpeculationEagerness::kDefault));
+      blink::mojom::SpeculationEagerness::kConservative));
   candidates.push_back(CreateCandidate(
       blink::mojom::SpeculationAction::kPrefetch, "/candidate2.html",
-      blink::mojom::SpeculationEagerness::kDefault));
+      blink::mojom::SpeculationEagerness::kConservative));
 
   preloading_decider->UpdateSpeculationCandidates(candidates);
   // It should not pass kDefault candidates directly
diff --git a/content/browser/renderer_host/indexed_db_client_state_checker_factory.cc b/content/browser/renderer_host/indexed_db_client_state_checker_factory.cc
index f31dbeb..f3714c1b 100644
--- a/content/browser/renderer_host/indexed_db_client_state_checker_factory.cc
+++ b/content/browser/renderer_host/indexed_db_client_state_checker_factory.cc
@@ -108,11 +108,17 @@
       mojo::PendingReceiver<storage::mojom::IndexedDBClientKeepActive>
           keep_active,
       RequireClientToBeActiveCallback callback) override {
+    // This is the only reason that we need to keep the client active.
+    CHECK_EQ(reason, storage::mojom::DisallowClientActivationReason::
+                         kClientEventIsTriggered);
     bool was_active = CheckIfClientWasActive(reason);
     if (was_active) {
       // If the document is active, we need to register a non sticky feature to
       // prevent putting it into BFCache until the IndexedDB connection is
       // successfully closed and the context is automatically destroyed.
+      // Since `kClientEventIsTriggered` is the only reason that should be
+      // passed to this function, the non-sticky feature will always be
+      // `kIndexedDBEvent`.
       KeepActiveReceiverContext context(
           static_cast<RenderFrameHostImpl&>(render_frame_host())
               .RegisterBackForwardCacheDisablingNonStickyFeature(
diff --git a/content/browser/renderer_host/indexed_db_client_state_checker_factory_unittest.cc b/content/browser/renderer_host/indexed_db_client_state_checker_factory_unittest.cc
index 3678cb4..4d63fba 100644
--- a/content/browser/renderer_host/indexed_db_client_state_checker_factory_unittest.cc
+++ b/content/browser/renderer_host/indexed_db_client_state_checker_factory_unittest.cc
@@ -15,7 +15,6 @@
 #include "content/public/test/prerender_test_util.h"
 #include "content/public/test/test_renderer_host.h"
 #include "content/public/test/web_contents_tester.h"
-#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace content {
diff --git a/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc b/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc
index 1dd76c1..36e3ea3 100644
--- a/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc
+++ b/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc
@@ -549,8 +549,9 @@
             parent_view->selection_controller()->GetVisibleRectBetweenBounds());
 }
 
+// Failing in sanitizer runs: https://crbug.com/1405296
 IN_PROC_BROWSER_TEST_P(TouchSelectionControllerClientAuraSiteIsolationTest,
-                       BasicSelectionIsolatedScrollMainframe) {
+                       DISABLED_BasicSelectionIsolatedScrollMainframe) {
   GURL test_url(embedded_test_server()->GetURL(
       "a.com", "/cross_site_iframe_factory.html?a(a)"));
   EXPECT_TRUE(NavigateToURL(shell(), test_url));
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
index bab1fcf..01db1739 100644
--- a/content/browser/renderer_host/navigation_request.cc
+++ b/content/browser/renderer_host/navigation_request.cc
@@ -8051,6 +8051,11 @@
   ContentBrowserClient* client = GetContentClient()->browser();
   client->LogWebFeatureForCurrentPage(initiator_render_frame_host,
                                       *optional_feature);
+  client->LogWebFeatureForCurrentPage(
+      initiator_render_frame_host,
+      IsInOutermostMainFrame()
+          ? blink::mojom::WebFeature::kPrivateNetworkAccessFetchedTopFrame
+          : blink::mojom::WebFeature::kPrivateNetworkAccessFetchedSubFrame);
 }
 
 void NavigationRequest::ComputePoliciesToCommit() {
diff --git a/content/public/test/attribution_simulator.h b/content/public/test/attribution_simulator.h
index 9abdf06..93abceb 100644
--- a/content/public/test/attribution_simulator.h
+++ b/content/public/test/attribution_simulator.h
@@ -9,8 +9,6 @@
 
 #include "content/public/browser/attribution_config.h"
 #include "content/public/browser/attribution_reporting.h"
-#include "third_party/abseil-cpp/absl/numeric/int128.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class Value;
@@ -45,13 +43,6 @@
 struct AttributionSimulationOptions {
   AttributionNoiseMode noise_mode = AttributionNoiseMode::kDefault;
 
-  // If set, the value is used to seed the random number generator used for
-  // noise. If null, the default source of randomness is used for noising and
-  // the simulation's output may vary between runs.
-  //
-  // Only used if `noise_mode` is `AttributionNoiseMode::kDefault`.
-  absl::optional<absl::uint128> noise_seed;
-
   AttributionConfig config;
 
   AttributionDelayMode delay_mode = AttributionDelayMode::kDefault;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 63fed1e..d716629 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -46,8 +46,6 @@
     "../browser/accessibility/test_browser_accessibility_delegate.h",
     "../browser/aggregation_service/aggregation_service_test_utils.cc",
     "../browser/aggregation_service/aggregation_service_test_utils.h",
-    "../browser/attribution_reporting/attribution_insecure_random_generator.cc",
-    "../browser/attribution_reporting/attribution_insecure_random_generator.h",
     "../browser/attribution_reporting/attribution_interop_parser.cc",
     "../browser/attribution_reporting/attribution_interop_parser.h",
     "../browser/attribution_reporting/attribution_parser_test_utils.cc",
@@ -2134,7 +2132,6 @@
     "../browser/attribution_reporting/attribution_data_host_manager_impl_unittest.cc",
     "../browser/attribution_reporting/attribution_debug_report_unittest.cc",
     "../browser/attribution_reporting/attribution_host_unittest.cc",
-    "../browser/attribution_reporting/attribution_insecure_random_generator_unittest.cc",
     "../browser/attribution_reporting/attribution_interop_parser_unittest.cc",
     "../browser/attribution_reporting/attribution_interop_unittest.cc",
     "../browser/attribution_reporting/attribution_manager_impl_unittest.cc",
@@ -2849,6 +2846,12 @@
     "//third_party/mesa_headers",
   ]
 
+  # Platforms where sqlite_dev_shell is defined.
+  if (is_win || is_mac || is_linux || is_chromeos) {
+    sources += [ "../browser/attribution_reporting/attribution_storage_sql_query_plans_unittest.cc" ]
+    deps += [ "../browser/attribution_reporting:sqlite_test_utils" ]
+  }
+
   if (is_chromeos_lacros) {
     deps += [
       "//chromeos/crosapi/mojom",
diff --git a/content/test/attribution_simulator_impl.cc b/content/test/attribution_simulator_impl.cc
index e72bba5..c976437 100644
--- a/content/test/attribution_simulator_impl.cc
+++ b/content/test/attribution_simulator_impl.cc
@@ -39,11 +39,8 @@
 #include "content/browser/attribution_reporting/aggregatable_attribution_utils.h"
 #include "content/browser/attribution_reporting/attribution_cookie_checker_impl.h"
 #include "content/browser/attribution_reporting/attribution_debug_report.h"
-#include "content/browser/attribution_reporting/attribution_default_random_generator.h"
-#include "content/browser/attribution_reporting/attribution_insecure_random_generator.h"
 #include "content/browser/attribution_reporting/attribution_manager_impl.h"
 #include "content/browser/attribution_reporting/attribution_observer.h"
-#include "content/browser/attribution_reporting/attribution_random_generator.h"
 #include "content/browser/attribution_reporting/attribution_report.h"
 #include "content/browser/attribution_reporting/attribution_report_sender.h"
 #include "content/browser/attribution_reporting/attribution_storage_delegate_impl.h"
@@ -174,18 +171,19 @@
   base::Value::Dict ToJson(const AttributionDebugReport& report,
                            base::Time time) const {
     base::Value::List report_body = report.ReportBody().Clone();
-    if (options.remove_report_ids) {
-      for (auto& value : report_body) {
-        base::Value::Dict* dict = value.GetIfDict();
-        DCHECK(dict);
+    for (auto& value : report_body) {
+      base::Value::Dict* dict = value.GetIfDict();
+      DCHECK(dict);
 
-        base::Value::Dict* body = dict->FindDict("body");
-        DCHECK(body);
+      base::Value::Dict* body = dict->FindDict("body");
+      DCHECK(body);
 
+      if (options.remove_report_ids) {
         body->Remove("report_id");
-        AdjustScheduledReportTime(*body,
-                                  report.GetOriginalReportTimeForTesting());
       }
+
+      AdjustScheduledReportTime(*body,
+                                report.GetOriginalReportTimeForTesting());
     }
 
     base::Value::Dict value;
@@ -426,14 +424,6 @@
   base::ranges::stable_sort(*events, /*comp=*/{}, &GetEventTime);
   task_environment.FastForwardBy(GetEventTime(events->at(0)) - time_origin);
 
-  std::unique_ptr<AttributionRandomGenerator> rng;
-  if (options.noise_seed.has_value()) {
-    rng = std::make_unique<AttributionInsecureRandomGenerator>(
-        *options.noise_seed);
-  } else {
-    rng = std::make_unique<AttributionDefaultRandomGenerator>();
-  }
-
   auto* storage_partition = static_cast<StoragePartitionImpl*>(
       browser_context.GetDefaultStoragePartition());
 
@@ -443,8 +433,7 @@
       /*max_pending_events=*/std::numeric_limits<size_t>::max(),
       /*special_storage_policy=*/nullptr,
       AttributionStorageDelegateImpl::CreateForTesting(
-          options.noise_mode, options.delay_mode, options.config,
-          std::move(rng)),
+          options.noise_mode, options.delay_mode, options.config),
       std::make_unique<AttributionCookieCheckerImpl>(storage_partition),
       std::make_unique<FakeReportSender>(), storage_partition,
       base::ThreadPool::CreateUpdateableSequencedTaskRunner(
diff --git a/content/test/attribution_simulator_impl_unittest.cc b/content/test/attribution_simulator_impl_unittest.cc
index 156b012..1ffa92d 100644
--- a/content/test/attribution_simulator_impl_unittest.cc
+++ b/content/test/attribution_simulator_impl_unittest.cc
@@ -13,13 +13,11 @@
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/path_service.h"
-#include "base/strings/abseil_string_number_conversions.h"
 #include "base/test/values_test_util.h"
 #include "base/values.h"
 #include "content/public/browser/attribution_reporting.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/numeric/int128.h"
 
 namespace content {
 namespace {
@@ -85,13 +83,6 @@
       options.noise_mode = AttributionNoiseMode::kDefault;
     }
   }
-
-  if (const std::string* noise_seed = dict.FindStringKey("noise_seed")) {
-    absl::uint128 value;
-    ASSERT_TRUE(base::HexStringToUInt128(*noise_seed, &value))
-        << "invalid noise seed: " << *noise_seed;
-    options.noise_seed = value;
-  }
 }
 
 class AttributionSimulatorImplTest
diff --git a/content/test/attribution_simulator_input_parser.cc b/content/test/attribution_simulator_input_parser.cc
index 3b232fa5..0ecaca4 100644
--- a/content/test/attribution_simulator_input_parser.cc
+++ b/content/test/attribution_simulator_input_parser.cc
@@ -66,7 +66,7 @@
       return absl::nullopt;
 
     static constexpr char kKeyCookies[] = "cookies";
-    if (base::Value* cookies = input.FindKey(kKeyCookies)) {
+    if (base::Value* cookies = input.GetDict().Find(kKeyCookies)) {
       auto context = PushContext(kKeyCookies);
       ParseList(
           std::move(*cookies),
@@ -75,7 +75,7 @@
     }
 
     static constexpr char kKeyDataClears[] = "data_clears";
-    if (base::Value* data_clears = input.FindKey(kKeyDataClears)) {
+    if (base::Value* data_clears = input.GetDict().Find(kKeyDataClears)) {
       auto context = PushContext(kKeyDataClears);
       ParseList(
           std::move(*data_clears),
@@ -84,7 +84,7 @@
     }
 
     static constexpr char kKeySources[] = "sources";
-    if (base::Value* sources = input.FindKey(kKeySources)) {
+    if (base::Value* sources = input.GetDict().Find(kKeySources)) {
       auto context = PushContext(kKeySources);
       ParseList(
           std::move(*sources),
@@ -93,7 +93,7 @@
     }
 
     static constexpr char kKeyTriggers[] = "triggers";
-    if (base::Value* triggers = input.FindKey(kKeyTriggers)) {
+    if (base::Value* triggers = input.GetDict().Find(kKeyTriggers)) {
       auto context = PushContext(kKeyTriggers);
       ParseList(
           std::move(*triggers),
diff --git a/content/test/data/accessibility/aria/aria-insertion-deletion-expected-uia-win.txt b/content/test/data/accessibility/aria/aria-insertion-deletion-expected-uia-win.txt
new file mode 100644
index 0000000..22321bf
--- /dev/null
+++ b/content/test/data/accessibility/aria/aria-insertion-deletion-expected-uia-win.txt
@@ -0,0 +1,9 @@
+Document LocalizedControlType='document'
+++Group LocalizedControlType='group' IsControlElement=false
+++++Text LocalizedControlType='text' Name='My favorite browser is '
+++++Group LocalizedControlType='deletion'
+++++++Text LocalizedControlType='text' Name='ABC'
+++++Text LocalizedControlType='text' Name=' '
+++++Group LocalizedControlType='insertion'
+++++++Text LocalizedControlType='text' Name='Chrome'
+++++Text LocalizedControlType='text' Name='!'
diff --git a/content/test/data/accessibility/aria/aria-insertion-deletion.html b/content/test/data/accessibility/aria/aria-insertion-deletion.html
index 45ed847..cb776f7 100644
--- a/content/test/data/accessibility/aria/aria-insertion-deletion.html
+++ b/content/test/data/accessibility/aria/aria-insertion-deletion.html
@@ -1,4 +1,7 @@
 <!DOCTYPE html>
+<!--
+@UIA-WIN-ALLOW:LocalizedControlType*
+-->
 <html>
 <head>
 <style>
diff --git a/content/test/data/accessibility/html/del-expected-uia-win.txt b/content/test/data/accessibility/html/del-expected-uia-win.txt
index 50bd303..f7944fab1 100644
--- a/content/test/data/accessibility/html/del-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/del-expected-uia-win.txt
@@ -1,5 +1,5 @@
-Document
-++Group IsControlElement=false
-++++Text Name='I am '
-++++Group IsControlElement=false
-++++++Text Name='vegetarian'
+Document LocalizedControlType='document'
+++Group LocalizedControlType='group' IsControlElement=false
+++++Text LocalizedControlType='text' Name='I am '
+++++Group LocalizedControlType='deletion' IsControlElement=false
+++++++Text LocalizedControlType='text' Name='vegetarian'
diff --git a/content/test/data/accessibility/html/del.html b/content/test/data/accessibility/html/del.html
index 86a608a..4223de2 100644
--- a/content/test/data/accessibility/html/del.html
+++ b/content/test/data/accessibility/html/del.html
@@ -1,4 +1,5 @@
 <!--
+@UIA-WIN-ALLOW:LocalizedControlType*
 -->
 <!DOCTYPE html>
 <html>
diff --git a/content/test/data/accessibility/html/s-expected-android-external.txt b/content/test/data/accessibility/html/s-expected-android-external.txt
index e96a8d0..55a7d80 100644
--- a/content/test/data/accessibility/html/s-expected-android-external.txt
+++ b/content/test/data/accessibility/html/s-expected-android-external.txt
@@ -1,2 +1,3 @@
 WebView focusable focused scrollable actions:[CLEAR_FOCUS, AX_FOCUS] bundle:[chromeRole="rootWebArea"]
-++TextView text:"My car is blue." actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="genericContainer"]
\ No newline at end of file
+++View actions:[AX_FOCUS] bundle:[chromeRole="genericContainer"]
+++++View text:"My car is blue." actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="contentDeletion", roleDescription="deletion"]
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/s-expected-android.txt b/content/test/data/accessibility/html/s-expected-android.txt
index 01d5ebf..263c24e 100644
--- a/content/test/data/accessibility/html/s-expected-android.txt
+++ b/content/test/data/accessibility/html/s-expected-android.txt
@@ -1,2 +1,3 @@
 android.webkit.WebView focusable focused scrollable
-++android.widget.TextView name='My car is blue.'
\ No newline at end of file
+++android.view.View
+++++android.view.View role_description='deletion' name='My car is blue.'
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/s-expected-auralinux.txt b/content/test/data/accessibility/html/s-expected-auralinux.txt
index 8ed215f..22f74d1 100644
--- a/content/test/data/accessibility/html/s-expected-auralinux.txt
+++ b/content/test/data/accessibility/html/s-expected-auralinux.txt
@@ -1,3 +1,4 @@
 [document web]
 ++[section]
-++++[static] name='My car is blue.'
+++++[content deletion]
+++++++[static] name='My car is blue.'
diff --git a/content/test/data/accessibility/html/s-expected-blink.txt b/content/test/data/accessibility/html/s-expected-blink.txt
index 39c2febc..30f16d0 100644
--- a/content/test/data/accessibility/html/s-expected-blink.txt
+++ b/content/test/data/accessibility/html/s-expected-blink.txt
@@ -1,5 +1,6 @@
 rootWebArea
 ++genericContainer ignored
 ++++genericContainer
-++++++staticText name='My car is blue.'
-++++++++inlineTextBox name='My car is blue.'
+++++++contentDeletion
+++++++++staticText name='My car is blue.'
+++++++++++inlineTextBox name='My car is blue.'
diff --git a/content/test/data/accessibility/html/s-expected-fuchsia.txt b/content/test/data/accessibility/html/s-expected-fuchsia.txt
index 17aee95..b45826e 100644
--- a/content/test/data/accessibility/html/s-expected-fuchsia.txt
+++ b/content/test/data/accessibility/html/s-expected-fuchsia.txt
@@ -1,5 +1,6 @@
 UNKNOWN focusable has_input_focus
 ++UNKNOWN hidden
 ++++UNKNOWN
-++++++STATIC_TEXT label='My car is blue.'
-++++++++UNKNOWN label='My car is blue.'
\ No newline at end of file
+++++++UNKNOWN
+++++++++STATIC_TEXT label='My car is blue.'
+++++++++++UNKNOWN label='My car is blue.'
diff --git a/content/test/data/accessibility/html/s-expected-mac.txt b/content/test/data/accessibility/html/s-expected-mac.txt
index 0220ec2c..cce1fded 100644
--- a/content/test/data/accessibility/html/s-expected-mac.txt
+++ b/content/test/data/accessibility/html/s-expected-mac.txt
@@ -1,3 +1,4 @@
 AXWebArea
 ++AXGroup
-++++AXStaticText AXValue='My car is blue.'
+++++AXGroup AXSubrole=AXDeleteStyleGroup
+++++++AXStaticText AXValue='My car is blue.'
diff --git a/content/test/data/accessibility/html/s-expected-uia-win.txt b/content/test/data/accessibility/html/s-expected-uia-win.txt
index 5d7ed88..074bf78 100644
--- a/content/test/data/accessibility/html/s-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/s-expected-uia-win.txt
@@ -1 +1,4 @@
-#<skip - Doesn't have an accessible>
+Document LocalizedControlType='document'
+++Group LocalizedControlType='group' IsControlElement=false
+++++Group LocalizedControlType='deletion' IsControlElement=false
+++++++Text LocalizedControlType='text' Name='My car is blue.'
diff --git a/content/test/data/accessibility/html/s-expected-win.txt b/content/test/data/accessibility/html/s-expected-win.txt
index 5d7ed88..340bc8cc 100644
--- a/content/test/data/accessibility/html/s-expected-win.txt
+++ b/content/test/data/accessibility/html/s-expected-win.txt
@@ -1 +1,4 @@
-#<skip - Doesn't have an accessible>
+ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
+++IA2_ROLE_SECTION
+++++IA2_ROLE_CONTENT_DELETION
+++++++ROLE_SYSTEM_STATICTEXT name='My car is blue.'
diff --git a/content/test/data/accessibility/html/s.html b/content/test/data/accessibility/html/s.html
index d17bffb..2055b77 100644
--- a/content/test/data/accessibility/html/s.html
+++ b/content/test/data/accessibility/html/s.html
@@ -1,3 +1,6 @@
+<!--
+@UIA-WIN-ALLOW:LocalizedControlType*
+-->
 <!DOCTYPE html>
 <html>
 <body>
diff --git a/content/test/data/attribution_reporting/simulator/noise_seed.input.json b/content/test/data/attribution_reporting/simulator/noise_seed.input.json
deleted file mode 100644
index e78b790..0000000
--- a/content/test/data/attribution_reporting/simulator/noise_seed.input.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "sources": [
-    {
-      "timestamp": "1643235573000",
-      "source_origin": "https://s.test",
-      "reporting_origin": "https://r.test",
-      "source_type": "navigation",
-      "Attribution-Reporting-Register-Source": {
-        "destination": "https://d.test",
-        "source_event_id": "123"
-      }
-    }
-  ]
-}
diff --git a/content/test/data/attribution_reporting/simulator/noise_seed.options.json b/content/test/data/attribution_reporting/simulator/noise_seed.options.json
deleted file mode 100644
index e5e1fe6..0000000
--- a/content/test/data/attribution_reporting/simulator/noise_seed.options.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "noise_mode": "default",
-  "noise_seed": "0x3"
-}
diff --git a/content/test/data/attribution_reporting/simulator/noise_seed.output.json b/content/test/data/attribution_reporting/simulator/noise_seed.output.json
deleted file mode 100644
index 43f62521..0000000
--- a/content/test/data/attribution_reporting/simulator/noise_seed.output.json
+++ /dev/null
@@ -1,49 +0,0 @@
-{
-  "event_level_reports": [
-    {
-      "report": {
-        "attribution_destination": "https://d.test",
-        "randomized_trigger_rate": 0.0024,
-        "scheduled_report_time": "1643411973",
-        "source_event_id": "123",
-        "source_type": "navigation",
-        "trigger_data": "5"
-      },
-      "intended_report_time": "1643411973000",
-      "report_url": "https://r.test/.well-known/attribution-reporting/report-event-attribution",
-      "test_info": {
-        "randomized_trigger": true
-      }
-    },
-    {
-      "report": {
-        "attribution_destination": "https://d.test",
-        "randomized_trigger_rate": 0.0024,
-        "scheduled_report_time": "1643411973",
-        "source_event_id": "123",
-        "source_type": "navigation",
-        "trigger_data": "1"
-      },
-      "intended_report_time": "1643411973000",
-      "report_url": "https://r.test/.well-known/attribution-reporting/report-event-attribution",
-      "test_info": {
-        "randomized_trigger": true
-      }
-    },
-    {
-      "report": {
-        "attribution_destination": "https://d.test",
-        "randomized_trigger_rate": 0.0024,
-        "scheduled_report_time": "1645831173",
-        "source_event_id": "123",
-        "source_type": "navigation",
-        "trigger_data": "3"
-      },
-      "intended_report_time": "1645831173000",
-      "report_url": "https://r.test/.well-known/attribution-reporting/report-event-attribution",
-      "test_info": {
-        "randomized_trigger": true
-      }
-    }
-  ]
-}
diff --git a/content/test/data/back_forward_cache/page_with_indexedDB.js b/content/test/data/back_forward_cache/page_with_indexedDB.js
index 3580411c..e4ee104 100644
--- a/content/test/data/back_forward_cache/page_with_indexedDB.js
+++ b/content/test/data/back_forward_cache/page_with_indexedDB.js
@@ -62,16 +62,22 @@
   };
 }
 
-function startIndexedDBTransaction() {
+function createIndexedDBTransaction() {
   let transaction = db.transaction(['store'], 'readwrite');
-  let store = transaction.objectStore('store');
+  transaction.oncomplete = () => {
+    window.domAutomationController.send('transaction_completed');
+  };
+  return [transaction, transaction.objectStore('store')];
+}
+
+function startIndexedDBTransaction() {
+  const [_, store] = createIndexedDBTransaction();
   store.put("key", "value");
 }
 
 function runInfiniteIndexedDBTransactionLoop() {
-  let transaction = db.transaction(['store'], 'readwrite');
-  let store = transaction.objectStore('store');
-  let infiniteLoop = () => {
+  const [_, store] = createIndexedDBTransaction();
+  const infiniteLoop = () => {
     let request = store.put("key", "value");
     request.onsuccess = infiniteLoop;
   }
@@ -86,10 +92,9 @@
 
 function registerPagehideToStartTransaction() {
   addEventListener('pagehide', () => {
-    let transaction = db.transaction(['store'], 'readwrite');
-    let store = transaction.objectStore('store');
+    const [_, store] = createIndexedDBTransaction();
     store.put("key", "value");
-
+    window.domAutomationController.send('transaction_created');
     // Queue a request to close the connection.
     db.close();
   });
@@ -97,8 +102,7 @@
 
 function registerPagehideToStartAndCommitTransaction() {
   addEventListener('pagehide', () => {
-    let transaction = db.transaction(['store'], 'readwrite');
-    let store = transaction.objectStore('store');
+    const [transaction, store] = createIndexedDBTransaction();
     store.put("key", "value");
 
     // Call commit to run the transaction right away.
@@ -107,3 +111,7 @@
     db.close();
   });
 }
+
+function registerPagehideToStartRunningInfiniteIndexedDBTransactionLoop() {
+  addEventListener('pagehide', runInfiniteIndexedDBTransactionLoop);
+}
diff --git a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
index 5c3a9f4..bf6b10f93 100644
--- a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
@@ -412,6 +412,7 @@
 crbug.com/1382332 [ android-chromium android-s android-sm-a135m angle-disabled arm no-passthrough renderer-skia-gl target-cpu-32 ] Pixel_MediaRecorderFromVideoElement [ Failure ]
 crbug.com/1382332 [ android ] Pixel_MediaRecorderFromVideoElementWithOoprCanvasDisabled [ Failure ]
 crbug.com/1382332 [ fuchsia ] Pixel_MediaRecorderFromVideoElementWithOoprCanvasDisabled [ Failure ]
+crbug.com/1382332 [ linux nvidia-0x2184 passthrough debug angle-vulkan ] Pixel_MediaRecorderFromVideoElementWithOoprCanvasDisabled [ Failure ]
 
 # WebGL tests are seeing occasional hangs on Linux FYI Release (AMD RX 5500 XT).
 crbug.com/1396451 [ linux desktop amd-0x7340 ] Pixel_WebGLSadCanvas [ RetryOnFailure ]
diff --git a/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt
index 50818f5b..7111f35 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt
@@ -89,6 +89,24 @@
 
 
 crbug.com/1371749 [ mac-x86_64 ] WebCodecs_EncodeDecode_offscreen_avc1.42001E_prefer-hardware [ Failure ]
+
+
+# TexImage2d tests crashes GPU on Sherlock devices.
+crbug.com/1400465 [ fuchsia fuchsia-board-sherlock ] WebCodecs_TexImage2d_* [ Failure ]
+
+# EncodeDecode tests fail to call flush on the decoder.
+crbug.com/1400465 [ fuchsia fuchsia-board-sherlock ] WebCodecs_EncodeDecode_* [ Failure ]
+
+# Camera tests fail with NotFoundError on Sherlock devices.
+crbug.com/1400512 [ fuchsia fuchsia-board-sherlock ] WebCodecs_DrawImage_camera [ Failure ]
+crbug.com/1400512 [ fuchsia fuchsia-board-sherlock ] WebCodecs_Encode_camera_* [ Failure ]
+crbug.com/1400512 [ fuchsia fuchsia-board-sherlock ] WebCodecs_GPUExternalTexture_expired_camera [ Failure ]
+crbug.com/1400512 [ fuchsia fuchsia-board-sherlock ] WebCodecs_GPUExternalTexture_expired_worker_camera [ Failure ]
+crbug.com/1400512 [ fuchsia fuchsia-board-sherlock ] WebCodecs_TexImage2d_camera [ Failure ]
+crbug.com/1400512 [ fuchsia fuchsia-board-sherlock ] WebCodecs_copyTo_camera [ Failure ]
+crbug.com/1400512 [ fuchsia fuchsia-board-sherlock ] WebCodecs_device_destroy_expired_texture_camera [ Failure ]
+crbug.com/1400512 [ fuchsia fuchsia-board-sherlock ] WebCodecs_texture_expired_from_destroyed_device_camera [ Failure ]
+
 #######################################################################
 # Automated Entries After This Point - Do Not Manually Add Below Here #
 #######################################################################
diff --git a/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container_manager.cc b/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container_manager.cc
index 1a45330a..19f35ee8 100644
--- a/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container_manager.cc
+++ b/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container_manager.cc
@@ -221,11 +221,6 @@
       // MimeHandlerViewGuest.
       return;
     }
-    // TODO(crbug.com/1286950) Remove this once a decision is made on
-    // deprecation of the <param> URL functionality.
-    std::set<std::string> kPdfMimeTypes{"application/pdf", "text/pdf"};
-    bool is_pdf = kPdfMimeTypes.count(frame_container->mime_type());
-    frame_container->plugin_element().UseCountParamUrlUsageIfNeeded(is_pdf);
 
     frame_container->set_element_instance_id(element_instance_id);
     auto* content_frame = frame_container->GetContentFrame();
diff --git a/fuchsia_web/common/init_logging.cc b/fuchsia_web/common/init_logging.cc
index a26ecc7..fc0d98a 100644
--- a/fuchsia_web/common/init_logging.cc
+++ b/fuchsia_web/common/init_logging.cc
@@ -20,8 +20,7 @@
 bool InitLoggingFromCommandLine(const base::CommandLine& command_line) {
   logging::LoggingSettings settings;
   if (command_line.GetSwitchValueASCII(kEnableLogging) == "stderr") {
-    settings.logging_dest =
-        logging::LOG_TO_STDERR | logging::LOG_TO_SYSTEM_DEBUG_LOG;
+    settings.logging_dest = logging::LOG_TO_STDERR;
   } else {
     settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
   }
diff --git a/fuchsia_web/common/test/fake_feedback_service.cc b/fuchsia_web/common/test/fake_feedback_service.cc
index a579eeb6..b768331 100644
--- a/fuchsia_web/common/test/fake_feedback_service.cc
+++ b/fuchsia_web/common/test/fake_feedback_service.cc
@@ -8,6 +8,7 @@
 #include <lib/sys/component/cpp/testing/realm_builder.h>
 #include <lib/sys/cpp/outgoing_directory.h>
 
+#include <memory>
 #include <utility>
 
 #include "fuchsia_web/common/test/test_realm_support.h"
@@ -19,11 +20,17 @@
 
 namespace test {
 
-FakeFeedbackService::FakeFeedbackService(
+FakeFeedbackService::FakeFeedbackService() = default;
+
+FakeFeedbackService::~FakeFeedbackService() = default;
+
+void FakeFeedbackService::RouteToChild(
     ::component_testing::RealmBuilder& realm_builder,
     std::string_view child_name) {
   static constexpr char kFeedbackService[] = "fake_feedback";
-  realm_builder.AddLocalChild(kFeedbackService, this);
+  realm_builder.AddLocalChild(kFeedbackService, []() {
+    return std::make_unique<FakeFeedbackService>();
+  });
   realm_builder.AddRoute(Route{
       .capabilities =
           {Protocol{fuchsia::feedback::ComponentDataRegister::Name_},
@@ -32,15 +39,11 @@
       .targets = {ChildRef{child_name}}});
 }
 
-FakeFeedbackService::~FakeFeedbackService() = default;
-
-void FakeFeedbackService::Start(
-    std::unique_ptr<::component_testing::LocalComponentHandles> mock_handles) {
-  handles_ = std::move(mock_handles);
-  ASSERT_EQ(handles_->outgoing()->AddPublicService(
+void FakeFeedbackService::OnStart() {
+  ASSERT_EQ(outgoing()->AddPublicService(
                 component_data_register_bindings_.GetHandler(this)),
             ZX_OK);
-  ASSERT_EQ(handles_->outgoing()->AddPublicService(
+  ASSERT_EQ(outgoing()->AddPublicService(
                 crash_reporting_product_register_bindings_.GetHandler(this)),
             ZX_OK);
 }
diff --git a/fuchsia_web/common/test/fake_feedback_service.h b/fuchsia_web/common/test/fake_feedback_service.h
index fa3d049..4669eb1 100644
--- a/fuchsia_web/common/test/fake_feedback_service.h
+++ b/fuchsia_web/common/test/fake_feedback_service.h
@@ -9,7 +9,6 @@
 #include <lib/fidl/cpp/binding_set.h>
 #include <lib/sys/component/cpp/testing/realm_builder_types.h>
 
-#include <memory>
 #include <string_view>
 
 namespace component_testing {
@@ -24,17 +23,22 @@
 class FakeFeedbackService
     : public ::fuchsia::feedback::ComponentDataRegister,
       public ::fuchsia::feedback::CrashReportingProductRegister,
-      public ::component_testing::LocalComponent {
+      public ::component_testing::LocalComponentImpl {
  public:
-  FakeFeedbackService(::component_testing::RealmBuilder& realm_builder,
-                      std::string_view child_name);
+  FakeFeedbackService();
   FakeFeedbackService(const FakeFeedbackService&) = delete;
   FakeFeedbackService& operator=(const FakeFeedbackService&) = delete;
   ~FakeFeedbackService() override;
 
-  // ::component_testing::LocalComponent:
-  void Start(std::unique_ptr<::component_testing::LocalComponentHandles>
-                 mock_handles) override;
+  // Registers a LocalComponentFactory function for the FakeFeedbackService with
+  // RealmBuilder and plumbs its protocols to the peer component identified
+  // by the given child_name. Note, each constructed instance of
+  // FakeFeedbackService supports one RealmBuilder instance.
+  static void RouteToChild(::component_testing::RealmBuilder& realm_builder,
+                           std::string_view child_name);
+
+  // ::component_testing::LocalComponentImpl:
+  void OnStart() override;
 
   // ::fuchsia::feedback::ComponentDataRegister:
   void Upsert(::fuchsia::feedback::ComponentData data,
@@ -52,7 +56,6 @@
       component_data_register_bindings_;
   fidl::BindingSet<::fuchsia::feedback::CrashReportingProductRegister>
       crash_reporting_product_register_bindings_;
-  std::unique_ptr<::component_testing::LocalComponentHandles> handles_;
 };
 
 }  // namespace test
diff --git a/fuchsia_web/runners/cast/test/BUILD.gn b/fuchsia_web/runners/cast/test/BUILD.gn
index 9e94504..c87e193 100644
--- a/fuchsia_web/runners/cast/test/BUILD.gn
+++ b/fuchsia_web/runners/cast/test/BUILD.gn
@@ -18,7 +18,6 @@
   ]
   public_deps = [
     "//fuchsia_web/common/test:test_support",
-    "//media/fuchsia/audio:test_support_components",
     "//third_party/abseil-cpp:absl",
     "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.camera3",
     "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.legacymetrics",
@@ -31,6 +30,7 @@
     "//fuchsia_web/runners:cast_runner_core",
     "//fuchsia_web/runners/cast/fidl",
     "//media/fuchsia/audio:test_support",
+    "//media/fuchsia/audio:test_support_components",
     "//testing/gtest",
     "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.buildinfo",
     "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.fonts",
diff --git a/fuchsia_web/runners/cast/test/cast_runner_launcher.cc b/fuchsia_web/runners/cast/test/cast_runner_launcher.cc
index 248ea90..2835b52 100644
--- a/fuchsia_web/runners/cast/test/cast_runner_launcher.cc
+++ b/fuchsia_web/runners/cast/test/cast_runner_launcher.cc
@@ -21,9 +21,13 @@
 #include <fuchsia/ui/scenic/cpp/fidl.h>
 #include <fuchsia/web/cpp/fidl.h>
 
+#include <memory>
+#include <utility>
+
 #include "base/command_line.h"
 #include "fuchsia_web/common/test/test_realm_support.h"
 #include "fuchsia_web/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h"
+#include "media/fuchsia/audio/fake_audio_device_enumerator_local_component.h"
 
 using ::component_testing::ChildRef;
 using ::component_testing::Directory;
@@ -53,9 +57,9 @@
                                 kSwitchesToCopy, std::size(kSwitchesToCopy));
   AppendCommandLineArguments(realm_builder, kCastRunnerService, command_line);
 
-  // Run the fake fuchsia.feedback service; plumbing its protocols to
-  // cast_runner.
-  fake_feedback_service_.emplace(realm_builder, kCastRunnerService);
+  // Register the fake fuchsia.feedback service component; plumbing its
+  // protocols to cast_runner.
+  FakeFeedbackService::RouteToChild(realm_builder, kCastRunnerService);
 
   AddSyslogRoutesFromParent(realm_builder, kCastRunnerService);
   AddVulkanRoutesFromParent(realm_builder, kCastRunnerService);
@@ -88,8 +92,13 @@
 
   // Provide a fake Cast "agent", providing some necessary services.
   static constexpr char kFakeCastAgentName[] = "fake-cast-agent";
-  fake_cast_agent_.emplace();
-  realm_builder.AddLocalChild(kFakeCastAgentName, &fake_cast_agent_.value());
+  auto fake_cast_agent = std::make_unique<FakeCastAgent>();
+  fake_cast_agent_ = fake_cast_agent.get();
+  realm_builder.AddLocalChild(
+      kFakeCastAgentName,
+      [fake_cast_agent = std::move(fake_cast_agent)]() mutable {
+        return std::move(fake_cast_agent);
+      });
   realm_builder.AddRoute(
       Route{.capabilities =
                 {
@@ -105,9 +114,9 @@
   if (runner_features_ & kCastRunnerFeaturesFakeAudioDeviceEnumerator) {
     static constexpr char kAudioDeviceEnumerator[] =
         "fake_audio_device_enumerator";
-    fake_audio_device_enumerator_.emplace();
-    realm_builder.AddLocalChild(kAudioDeviceEnumerator,
-                                &fake_audio_device_enumerator_.value());
+    realm_builder.AddLocalChild(kAudioDeviceEnumerator, []() {
+      return std::make_unique<media::FakeAudioDeviceEnumeratorLocalComponent>();
+    });
     realm_builder.AddRoute(
         Route{.capabilities = {Protocol{
                   fuchsia::media::AudioDeviceEnumerator::Name_}},
diff --git a/fuchsia_web/runners/cast/test/cast_runner_launcher.h b/fuchsia_web/runners/cast/test/cast_runner_launcher.h
index 1f1fd71..c35db130 100644
--- a/fuchsia_web/runners/cast/test/cast_runner_launcher.h
+++ b/fuchsia_web/runners/cast/test/cast_runner_launcher.h
@@ -14,7 +14,6 @@
 #include "fuchsia_web/common/test/fake_feedback_service.h"
 #include "fuchsia_web/runners/cast/test/cast_runner_features.h"
 #include "fuchsia_web/runners/cast/test/fake_cast_agent.h"
-#include "media/fuchsia/audio/fake_audio_device_enumerator_local_component.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace test {
@@ -36,12 +35,9 @@
  private:
   const CastRunnerFeatures runner_features_;
 
-  absl::optional<media::FakeAudioDeviceEnumeratorLocalComponent>
-      fake_audio_device_enumerator_;
-  absl::optional<FakeCastAgent> fake_cast_agent_;
-  absl::optional<FakeFeedbackService> fake_feedback_service_;
-
   absl::optional<::component_testing::RealmRoot> realm_root_;
+
+  raw_ptr<FakeCastAgent> fake_cast_agent_ = nullptr;
 };
 
 }  // namespace test
diff --git a/fuchsia_web/runners/cast/test/fake_cast_agent.cc b/fuchsia_web/runners/cast/test/fake_cast_agent.cc
index 1e408e2..a2ac035 100644
--- a/fuchsia_web/runners/cast/test/fake_cast_agent.cc
+++ b/fuchsia_web/runners/cast/test/fake_cast_agent.cc
@@ -4,6 +4,9 @@
 
 #include "fuchsia_web/runners/cast/test/fake_cast_agent.h"
 
+#include <memory>
+#include <utility>
+
 #include "base/check.h"
 #include "base/containers/contains.h"
 #include "base/run_loop.h"
@@ -18,7 +21,7 @@
 
 void FakeCastAgent::RegisterOnConnectClosure(base::StringPiece service,
                                              base::RepeatingClosure callback) {
-  DCHECK(!handles_);
+  DCHECK(!is_started_);
 
   std::string name{service};
   DCHECK(!base::Contains(on_connect_, name));
@@ -26,16 +29,13 @@
   on_connect_[std::move(name)] = std::move(callback);
 }
 
-void FakeCastAgent::Start(
-    std::unique_ptr<::component_testing::LocalComponentHandles> handles) {
-  handles_ = std::move(handles);
-
-  ASSERT_EQ(handles_->outgoing()->AddPublicService(
+void FakeCastAgent::OnStart() {
+  ASSERT_EQ(outgoing()->AddPublicService(
                 cors_exempt_header_provider_bindings_.GetHandler(this)),
             ZX_OK);
 
   for (const auto& [name, on_connect_closure] : on_connect_) {
-    ASSERT_EQ(handles_->outgoing()->AddPublicService(
+    ASSERT_EQ(outgoing()->AddPublicService(
                   std::make_unique<vfs::Service>(
                       [on_connect_closure = on_connect_closure](
                           zx::channel, async_dispatcher_t*) {
@@ -44,6 +44,8 @@
                   name),
               ZX_OK);
   }
+
+  is_started_ = true;
 }
 
 void FakeCastAgent::GetCorsExemptHeaderNames(
diff --git a/fuchsia_web/runners/cast/test/fake_cast_agent.h b/fuchsia_web/runners/cast/test/fake_cast_agent.h
index 8bb4f4f7..6c0be694 100644
--- a/fuchsia_web/runners/cast/test/fake_cast_agent.h
+++ b/fuchsia_web/runners/cast/test/fake_cast_agent.h
@@ -9,7 +9,6 @@
 #include <lib/fidl/cpp/binding_set.h>
 #include <lib/sys/component/cpp/testing/realm_builder.h>
 
-#include <memory>
 #include <vector>
 
 #include "base/containers/flat_map.h"
@@ -19,9 +18,9 @@
 
 namespace test {
 
-// LocalComponent implementation that offers some fake services that the
+// LocalComponentImpl implementation that offers some fake services that the
 // runner normally expects to have provided by the Cast "agent".
-class FakeCastAgent final : public ::component_testing::LocalComponent,
+class FakeCastAgent final : public ::component_testing::LocalComponentImpl,
                             public chromium::cast::CorsExemptHeaderProvider {
  public:
   FakeCastAgent();
@@ -36,21 +35,20 @@
   void RegisterOnConnectClosure(base::StringPiece service,
                                 base::RepeatingClosure callback);
 
-  // ::component_testing::LocalComponent implementation.
-  void Start(std::unique_ptr<::component_testing::LocalComponentHandles>
-                 handles) override;
+  // ::component_testing::LocalComponentImpl implementation.
+  void OnStart() override;
 
  private:
   // chromium::cast::CorsExemptHeaderProvider implementation.
   void GetCorsExemptHeaderNames(
       GetCorsExemptHeaderNamesCallback callback) override;
 
+  bool is_started_ = false;
+
   fidl::BindingSet<chromium::cast::CorsExemptHeaderProvider>
       cors_exempt_header_provider_bindings_;
 
   base::flat_map<std::string, base::RepeatingClosure> on_connect_;
-
-  std::unique_ptr<::component_testing::LocalComponentHandles> handles_;
 };
 
 }  // namespace test
diff --git a/fuchsia_web/webengine/test/context_provider_for_test_v2.cc b/fuchsia_web/webengine/test/context_provider_for_test_v2.cc
index 07e3c8d..93aa1fc9 100644
--- a/fuchsia_web/webengine/test/context_provider_for_test_v2.cc
+++ b/fuchsia_web/webengine/test/context_provider_for_test_v2.cc
@@ -15,9 +15,7 @@
 
 namespace {
 
-std::pair<std::unique_ptr<test::FakeFeedbackService>,
-          ::component_testing::RealmRoot>
-BuildRealm(base::CommandLine command_line) {
+::component_testing::RealmRoot BuildRealm(base::CommandLine command_line) {
   DCHECK(command_line.argv()[0].empty()) << "Must use NO_PROGRAM.";
 
   auto realm_builder = ::component_testing::RealmBuilder::Create();
@@ -32,8 +30,8 @@
   test::AppendCommandLineArguments(realm_builder, kContextProviderService,
                                    command_line);
 
-  auto fake_feedback_service = std::make_unique<test::FakeFeedbackService>(
-      realm_builder, kContextProviderService);
+  test::FakeFeedbackService::RouteToChild(realm_builder,
+                                          kContextProviderService);
 
   test::AddSyslogRoutesFromParent(realm_builder, kContextProviderService);
 
@@ -51,7 +49,7 @@
           .source = ::component_testing::ChildRef{kContextProviderService},
           .targets = {::component_testing::ParentRef{}}});
 
-  return {std::move(fake_feedback_service), realm_builder.Build()};
+  return realm_builder.Build();
 }
 
 }  // namespace
@@ -59,12 +57,11 @@
 // static
 ContextProviderForTest ContextProviderForTest::Create(
     const base::CommandLine& command_line) {
-  auto [fake_feedback_service, realm_root] = BuildRealm(command_line);
+  auto realm_root = BuildRealm(command_line);
   ::fuchsia::web::ContextProviderPtr context_provider;
   zx_status_t status = realm_root.Connect(context_provider.NewRequest());
   ZX_CHECK(status == ZX_OK, status) << "Connect to ContextProvider";
-  return ContextProviderForTest(std::move(fake_feedback_service),
-                                std::move(realm_root),
+  return ContextProviderForTest(std::move(realm_root),
                                 std::move(context_provider));
 }
 
@@ -75,11 +72,9 @@
 ContextProviderForTest::~ContextProviderForTest() = default;
 
 ContextProviderForTest::ContextProviderForTest(
-    std::unique_ptr<test::FakeFeedbackService> fake_feedback_service,
     ::component_testing::RealmRoot realm_root,
     ::fuchsia::web::ContextProviderPtr context_provider)
-    : fake_feedback_service_(std::move(fake_feedback_service)),
-      realm_root_(std::move(realm_root)),
+    : realm_root_(std::move(realm_root)),
       context_provider_(std::move(context_provider)) {}
 
 // static
diff --git a/fuchsia_web/webengine/test/context_provider_for_test_v2.h b/fuchsia_web/webengine/test/context_provider_for_test_v2.h
index 846f684..9b7ee09 100644
--- a/fuchsia_web/webengine/test/context_provider_for_test_v2.h
+++ b/fuchsia_web/webengine/test/context_provider_for_test_v2.h
@@ -9,14 +9,8 @@
 #include <lib/fidl/cpp/interface_request.h>
 #include <lib/sys/component/cpp/testing/realm_builder.h>
 
-#include <memory>
-
 #include "base/command_line.h"
 
-namespace test {
-class FakeFeedbackService;
-}
-
 // Starts a WebEngine and connects a ContextProvider instance for tests.
 // WebEngine logs will be included in the test output but not in the Fuchsia
 // system log.
@@ -34,11 +28,9 @@
 
  private:
   ContextProviderForTest(
-      std::unique_ptr<test::FakeFeedbackService> fake_feedback_service,
       ::component_testing::RealmRoot realm_root,
       ::fuchsia::web::ContextProviderPtr context_provider);
 
-  std::unique_ptr<test::FakeFeedbackService> fake_feedback_service_;
   ::component_testing::RealmRoot realm_root_;
   ::fuchsia::web::ContextProviderPtr context_provider_;
 };
diff --git a/fuchsia_web/webinstance_host/web_instance_host.cc b/fuchsia_web/webinstance_host/web_instance_host.cc
index 3758dc4..75b75c7 100644
--- a/fuchsia_web/webinstance_host/web_instance_host.cc
+++ b/fuchsia_web/webinstance_host/web_instance_host.cc
@@ -349,6 +349,24 @@
                     .set_availability(fcdecl::Availability::REQUIRED))));
 }
 
+void HandleCdmDataDirectoryParam(InstanceBuilder& builder,
+                                 fuchsia::web::CreateContextParams& params) {
+  if (!params.has_cdm_data_directory()) {
+    return;
+  }
+
+  static constexpr char kCdmDataPath[] = "/cdm_data";
+
+  builder.args().AppendSwitchNative(switches::kCdmDataDirectory, kCdmDataPath);
+  builder.ServeCdmDataDirectory(
+      std::move(*params.mutable_cdm_data_directory()));
+  if (params.has_cdm_data_quota_bytes()) {
+    builder.args().AppendSwitchNative(
+        switches::kCdmDataQuotaBytes,
+        base::NumberToString(params.cdm_data_quota_bytes()));
+  }
+}
+
 void HandleDataDirectoryParam(InstanceBuilder& builder,
                               fuchsia::web::CreateContextParams& params) {
   if (!params.has_data_directory()) {
@@ -429,6 +447,8 @@
     builder->AppendOffersForServices(services);
   }
 
+  HandleCdmDataDirectoryParam(*builder, params);
+
   HandleDataDirectoryParam(*builder, params);
 
   if (!HandleContentDirectoriesParam(*builder, params)) {
diff --git a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc
index 1016193..352bb72 100644
--- a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc
@@ -309,11 +309,14 @@
 AngleVulkanImageBacking::ProduceGLTexturePassthrough(
     SharedImageManager* manager,
     MemoryTypeTracker* tracker) {
-  if (!passthrough_texture_ && !InitializePassthroughTexture())
+  if (!passthrough_texture_ && !InitializePassthroughTexture()) {
     return nullptr;
+  }
 
+  std::vector<scoped_refptr<gles2::TexturePassthrough>> gl_textures = {
+      passthrough_texture_};
   return std::make_unique<GLTexturePassthroughGLCommonRepresentation>(
-      manager, this, this, tracker, passthrough_texture_);
+      manager, this, this, tracker, std::move(gl_textures));
 }
 
 std::unique_ptr<SkiaImageRepresentation> AngleVulkanImageBacking::ProduceSkia(
@@ -412,9 +415,6 @@
   ReleaseTextureANGLE();
 }
 
-void AngleVulkanImageBacking::GLTextureImageRepresentationRelease(
-    bool have_context) {}
-
 void AngleVulkanImageBacking::AcquireTextureANGLE() {
   gl::GLApi* api = gl::g_current_gl_context;
   GLuint texture = passthrough_texture_->service_id();
diff --git a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.h b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.h
index 8913fcb..daec0c06 100644
--- a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.h
+++ b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.h
@@ -51,7 +51,6 @@
   // GLTextureImageRepresentationClient implementation.
   bool GLTextureImageRepresentationBeginAccess(bool readonly) override;
   void GLTextureImageRepresentationEndAccess(bool readonly) override;
-  void GLTextureImageRepresentationRelease(bool have_context) override;
 
  private:
   class SkiaAngleVulkanImageRepresentation;
diff --git a/gpu/command_buffer/service/shared_image/gl_texture_common_representations.cc b/gpu/command_buffer/service/shared_image/gl_texture_common_representations.cc
index 87c9c58..291d10ae 100644
--- a/gpu/command_buffer/service/shared_image/gl_texture_common_representations.cc
+++ b/gpu/command_buffer/service/shared_image/gl_texture_common_representations.cc
@@ -5,7 +5,6 @@
 #include "gpu/command_buffer/service/shared_image/gl_texture_common_representations.h"
 
 #include "components/viz/common/resources/resource_format_utils.h"
-#include "components/viz/common/resources/resource_sizes.h"
 #include "gpu/command_buffer/service/shared_context_state.h"
 #include "gpu/command_buffer/service/skia_utils.h"
 #include "third_party/skia/include/core/SkColorSpace.h"
@@ -23,38 +22,37 @@
     SharedImageBacking* backing,
     GLTextureImageRepresentationClient* client,
     MemoryTypeTracker* tracker,
-    gles2::Texture* texture)
+    std::vector<raw_ptr<gles2::Texture>> textures)
     : GLTextureImageRepresentation(manager, backing, tracker),
       client_(client),
-      texture_(texture) {}
-
-GLTextureGLCommonRepresentation::~GLTextureGLCommonRepresentation() {
-  texture_ = nullptr;
-  if (client_)
-    client_->GLTextureImageRepresentationRelease(has_context());
+      textures_(std::move(textures)) {
+  DCHECK_EQ(textures_.size(), NumPlanesExpected());
 }
 
+GLTextureGLCommonRepresentation::~GLTextureGLCommonRepresentation() = default;
+
 gles2::Texture* GLTextureGLCommonRepresentation::GetTexture(int plane_index) {
-  DCHECK_EQ(plane_index, 0);
-  return texture_;
+  DCHECK(format().IsValidPlaneIndex(plane_index));
+  return textures_[plane_index];
 }
 
 bool GLTextureGLCommonRepresentation::BeginAccess(GLenum mode) {
-  DCHECK(mode_ == 0);
+  DCHECK_EQ(mode_, 0u);
   mode_ = mode;
   bool readonly = mode_ != GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM;
-  if (client_ && mode != GL_SHARED_IMAGE_ACCESS_MODE_OVERLAY_CHROMIUM)
+  if (client_ && mode != GL_SHARED_IMAGE_ACCESS_MODE_OVERLAY_CHROMIUM) {
     return client_->GLTextureImageRepresentationBeginAccess(readonly);
+  }
   return true;
 }
 
 void GLTextureGLCommonRepresentation::EndAccess() {
-  DCHECK(mode_ != 0);
-  GLenum current_mode = mode_;
+  DCHECK_NE(mode_, 0u);
+  bool readonly = mode_ != GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM;
   mode_ = 0;
-  if (client_)
-    return client_->GLTextureImageRepresentationEndAccess(
-        current_mode != GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM);
+  if (client_) {
+    return client_->GLTextureImageRepresentationEndAccess(readonly);
+  }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -66,44 +64,40 @@
         SharedImageBacking* backing,
         GLTextureImageRepresentationClient* client,
         MemoryTypeTracker* tracker,
-        scoped_refptr<gles2::TexturePassthrough> texture_passthrough)
+        std::vector<scoped_refptr<gles2::TexturePassthrough>> textures)
     : GLTexturePassthroughImageRepresentation(manager, backing, tracker),
       client_(client),
-      texture_passthrough_(std::move(texture_passthrough)) {
-  // TODO(https://crbug.com/1172769): Remove this CHECK.
-  CHECK(texture_passthrough_);
+      textures_(std::move(textures)) {
+  DCHECK_EQ(textures_.size(), NumPlanesExpected());
 }
 
 GLTexturePassthroughGLCommonRepresentation::
-    ~GLTexturePassthroughGLCommonRepresentation() {
-  texture_passthrough_.reset();
-  if (client_)
-    client_->GLTextureImageRepresentationRelease(has_context());
-}
+    ~GLTexturePassthroughGLCommonRepresentation() = default;
 
 const scoped_refptr<gles2::TexturePassthrough>&
 GLTexturePassthroughGLCommonRepresentation::GetTexturePassthrough(
     int plane_index) {
-  DCHECK_EQ(plane_index, 0);
-  return texture_passthrough_;
+  DCHECK(format().IsValidPlaneIndex(plane_index));
+  return textures_[plane_index];
 }
 
 bool GLTexturePassthroughGLCommonRepresentation::BeginAccess(GLenum mode) {
   DCHECK(mode_ == 0);
   mode_ = mode;
   bool readonly = mode_ != GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM;
-  if (client_ && mode != GL_SHARED_IMAGE_ACCESS_MODE_OVERLAY_CHROMIUM)
+  if (client_ && mode != GL_SHARED_IMAGE_ACCESS_MODE_OVERLAY_CHROMIUM) {
     return client_->GLTextureImageRepresentationBeginAccess(readonly);
+  }
   return true;
 }
 
 void GLTexturePassthroughGLCommonRepresentation::EndAccess() {
   DCHECK(mode_ != 0);
-  GLenum current_mode = mode_;
+  bool readonly = mode_ != GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM;
   mode_ = 0;
-  if (client_)
-    return client_->GLTextureImageRepresentationEndAccess(
-        current_mode != GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM);
+  if (client_) {
+    return client_->GLTextureImageRepresentationEndAccess(readonly);
+  }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -114,13 +108,13 @@
     SharedImageBacking* backing,
     GLTextureImageRepresentationClient* client,
     scoped_refptr<SharedContextState> context_state,
-    sk_sp<SkPromiseImageTexture> promise_texture,
+    std::vector<sk_sp<SkPromiseImageTexture>> promise_textures,
     MemoryTypeTracker* tracker)
     : SkiaImageRepresentation(manager, backing, tracker),
       client_(client),
       context_state_(std::move(context_state)),
-      promise_texture_(promise_texture) {
-  DCHECK(promise_texture_);
+      promise_textures_(std::move(promise_textures)) {
+  DCHECK_EQ(promise_textures_.size(), NumPlanesExpected());
 #if DCHECK_IS_ON()
   if (context_state_->GrContextIsGL())
     context_ = gl::GLContext::GetCurrent();
@@ -128,15 +122,7 @@
 }
 
 SkiaGLCommonRepresentation::~SkiaGLCommonRepresentation() {
-  if (write_surface_) {
-    DLOG(ERROR) << "SkiaImageRepresentation was destroyed while still "
-                << "open for write access.";
-  }
-  promise_texture_.reset();
-  if (client_) {
-    DCHECK(context_state_->GrContextIsGL());
-    client_->GLTextureImageRepresentationRelease(has_context());
-  }
+  DCHECK(write_surfaces_.empty());
 }
 
 std::vector<sk_sp<SkSurface>> SkiaGLCommonRepresentation::BeginWriteAccess(
@@ -155,27 +141,32 @@
     }
   }
 
-  if (write_surface_)
+  if (!write_surfaces_.empty()) {
+    // Write access is already in progress.
     return {};
+  }
 
-  if (!promise_texture_)
-    return {};
+  for (int plane = 0; plane < format().NumberOfPlanes(); ++plane) {
+    SkColorType sk_color_type = viz::ToClosestSkColorType(
+        /*gpu_compositing=*/true, format(), plane);
+    // Gray is not a renderable single channel format, but alpha is.
+    if (sk_color_type == kGray_8_SkColorType) {
+      sk_color_type = kAlpha_8_SkColorType;
+    }
+    auto surface = SkSurface::MakeFromBackendTexture(
+        context_state_->gr_context(),
+        promise_textures_[plane]->backendTexture(), surface_origin(),
+        final_msaa_count, sk_color_type,
+        backing()->color_space().GetAsFullRangeRGB().ToSkColorSpace(),
+        &surface_props);
+    if (!surface) {
+      write_surfaces_.clear();
+      return {};
+    }
+    write_surfaces_.push_back(std::move(surface));
+  }
 
-  SkColorType sk_color_type = viz::ToClosestSkColorType(
-      /*gpu_compositing=*/true, format());
-  // Gray is not a renderable single channel format, but alpha is.
-  if (sk_color_type == kGray_8_SkColorType)
-    sk_color_type = kAlpha_8_SkColorType;
-  auto surface = SkSurface::MakeFromBackendTexture(
-      context_state_->gr_context(), promise_texture_->backendTexture(),
-      surface_origin(), final_msaa_count, sk_color_type,
-      backing()->color_space().GetAsFullRangeRGB().ToSkColorSpace(),
-      &surface_props);
-  write_surface_ = surface;
-
-  if (!surface)
-    return {};
-  return {surface};
+  return write_surfaces_;
 }
 
 std::vector<sk_sp<SkPromiseImageTexture>>
@@ -192,21 +183,24 @@
     }
   }
 
-  if (!promise_texture_)
-    return {};
-  return {promise_texture_};
+  return promise_textures_;
 }
 
 void SkiaGLCommonRepresentation::EndWriteAccess() {
-  if (write_surface_) {
-    DCHECK(write_surface_->unique());
+  if (!write_surfaces_.empty()) {
+#if DCHECK_IS_ON()
+    for (auto& write_surface : write_surfaces_) {
+      DCHECK(write_surface->unique());
+    }
     CheckContext();
-    // TODO(ericrk): Keep the surface around for re-use.
-    write_surface_.reset();
+#endif
+    // TODO(ericrk): Keep the surfaces around for re-use.
+    write_surfaces_.clear();
   }
 
-  if (client_)
-    client_->GLTextureImageRepresentationEndAccess(false /* readonly */);
+  if (client_) {
+    client_->GLTextureImageRepresentationEndAccess(/*readonly=*/false);
+  }
 }
 
 std::vector<sk_sp<SkPromiseImageTexture>>
@@ -223,14 +217,13 @@
     }
   }
 
-  if (!promise_texture_)
-    return {};
-  return {promise_texture_};
+  return promise_textures_;
 }
 
 void SkiaGLCommonRepresentation::EndReadAccess() {
-  if (client_)
-    client_->GLTextureImageRepresentationEndAccess(true /* readonly */);
+  if (client_) {
+    client_->GLTextureImageRepresentationEndAccess(/*readonly=*/true);
+  }
 }
 
 bool SkiaGLCommonRepresentation::SupportsMultipleConcurrentReadAccess() {
@@ -239,8 +232,9 @@
 
 void SkiaGLCommonRepresentation::CheckContext() {
 #if DCHECK_IS_ON()
-  if (!context_state_->context_lost() && context_)
+  if (!context_state_->context_lost() && context_) {
     DCHECK(gl::GLContext::GetCurrent() == context_);
+  }
 #endif
 }
 
diff --git a/gpu/command_buffer/service/shared_image/gl_texture_common_representations.h b/gpu/command_buffer/service/shared_image/gl_texture_common_representations.h
index 06b45fb5..15bfadd 100644
--- a/gpu/command_buffer/service/shared_image/gl_texture_common_representations.h
+++ b/gpu/command_buffer/service/shared_image/gl_texture_common_representations.h
@@ -19,7 +19,6 @@
  public:
   virtual bool GLTextureImageRepresentationBeginAccess(bool readonly) = 0;
   virtual void GLTextureImageRepresentationEndAccess(bool readonly) = 0;
-  virtual void GLTextureImageRepresentationRelease(bool have_context) = 0;
 };
 
 // Representation of a GLTextureImageBacking or GLImageBacking
@@ -30,7 +29,7 @@
                                   SharedImageBacking* backing,
                                   GLTextureImageRepresentationClient* client,
                                   MemoryTypeTracker* tracker,
-                                  gles2::Texture* texture);
+                                  std::vector<raw_ptr<gles2::Texture>> texture);
   ~GLTextureGLCommonRepresentation() override;
 
  private:
@@ -40,7 +39,7 @@
   void EndAccess() override;
 
   const raw_ptr<GLTextureImageRepresentationClient> client_ = nullptr;
-  raw_ptr<gles2::Texture> texture_;
+  std::vector<raw_ptr<gles2::Texture>> textures_;
   GLenum mode_ = 0;
 };
 
@@ -58,7 +57,7 @@
       SharedImageBacking* backing,
       GLTextureImageRepresentationClient* client,
       MemoryTypeTracker* tracker,
-      scoped_refptr<gles2::TexturePassthrough> texture_passthrough);
+      std::vector<scoped_refptr<gles2::TexturePassthrough>> textures);
   ~GLTexturePassthroughGLCommonRepresentation() override;
 
  private:
@@ -69,7 +68,7 @@
   void EndAccess() override;
 
   const raw_ptr<GLTextureImageRepresentationClient> client_ = nullptr;
-  scoped_refptr<gles2::TexturePassthrough> texture_passthrough_;
+  std::vector<scoped_refptr<gles2::TexturePassthrough>> textures_;
   GLenum mode_ = 0;
 };
 
@@ -81,12 +80,13 @@
     virtual bool OnSkiaBeginReadAccess() = 0;
     virtual bool OnSkiaBeginWriteAccess() = 0;
   };
-  SkiaGLCommonRepresentation(SharedImageManager* manager,
-                             SharedImageBacking* backing,
-                             GLTextureImageRepresentationClient* client,
-                             scoped_refptr<SharedContextState> context_state,
-                             sk_sp<SkPromiseImageTexture> promise_texture,
-                             MemoryTypeTracker* tracker);
+  SkiaGLCommonRepresentation(
+      SharedImageManager* manager,
+      SharedImageBacking* backing,
+      GLTextureImageRepresentationClient* client,
+      scoped_refptr<SharedContextState> context_state,
+      std::vector<sk_sp<SkPromiseImageTexture>> promise_texture,
+      MemoryTypeTracker* tracker);
   ~SkiaGLCommonRepresentation() override;
 
   void SetBeginReadAccessCallback(
@@ -117,8 +117,8 @@
 
   const raw_ptr<GLTextureImageRepresentationClient> client_ = nullptr;
   scoped_refptr<SharedContextState> context_state_;
-  sk_sp<SkPromiseImageTexture> promise_texture_;
-  sk_sp<SkSurface> write_surface_;
+  std::vector<sk_sp<SkPromiseImageTexture>> promise_textures_;
+  std::vector<sk_sp<SkSurface>> write_surfaces_;
 #if DCHECK_IS_ON()
   raw_ptr<gl::GLContext> context_ = nullptr;
 #endif
diff --git a/gpu/command_buffer/service/shared_image/gl_texture_image_backing.cc b/gpu/command_buffer/service/shared_image/gl_texture_image_backing.cc
index 0dabd175..e2e70e4c 100644
--- a/gpu/command_buffer/service/shared_image/gl_texture_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/gl_texture_image_backing.cc
@@ -365,16 +365,19 @@
 GLTextureImageBacking::ProduceGLTexture(SharedImageManager* manager,
                                         MemoryTypeTracker* tracker) {
   DCHECK(texture_);
+  std::vector<raw_ptr<gles2::Texture>> gl_textures = {texture_};
   return std::make_unique<GLTextureGLCommonRepresentation>(
-      manager, this, nullptr, tracker, texture_);
+      manager, this, nullptr, tracker, std::move(gl_textures));
 }
 
 std::unique_ptr<GLTexturePassthroughImageRepresentation>
 GLTextureImageBacking::ProduceGLTexturePassthrough(SharedImageManager* manager,
                                                    MemoryTypeTracker* tracker) {
   DCHECK(passthrough_texture_);
+  std::vector<scoped_refptr<gles2::TexturePassthrough>> gl_textures = {
+      passthrough_texture_};
   return std::make_unique<GLTexturePassthroughGLCommonRepresentation>(
-      manager, this, nullptr, tracker, passthrough_texture_);
+      manager, this, nullptr, tracker, std::move(gl_textures));
 }
 
 std::unique_ptr<DawnImageRepresentation> GLTextureImageBacking::ProduceDawn(
@@ -437,9 +440,11 @@
         context_state->gr_context()->threadSafeProxy(), &backend_texture);
     cached_promise_texture_ = SkPromiseImageTexture::Make(backend_texture);
   }
+  std::vector<sk_sp<SkPromiseImageTexture>> promise_textures = {
+      cached_promise_texture_};
   return std::make_unique<SkiaGLCommonRepresentation>(
-      manager, this, nullptr, std::move(context_state), cached_promise_texture_,
-      tracker);
+      manager, this, nullptr, std::move(context_state),
+      std::move(promise_textures), tracker);
 }
 
 void GLTextureImageBacking::InitializeGLTexture(
diff --git a/gpu/command_buffer/service/shared_image/pbuffer_image_backing.cc b/gpu/command_buffer/service/shared_image/pbuffer_image_backing.cc
index 2f73deab..942c3efa 100644
--- a/gpu/command_buffer/service/shared_image/pbuffer_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/pbuffer_image_backing.cc
@@ -76,8 +76,10 @@
 PbufferImageBacking::ProduceGLTexturePassthrough(SharedImageManager* manager,
                                                  MemoryTypeTracker* tracker) {
   DCHECK(passthrough_texture_);
+  std::vector<scoped_refptr<gles2::TexturePassthrough>> gl_textures = {
+      passthrough_texture_};
   return std::make_unique<GLTexturePassthroughGLCommonRepresentation>(
-      manager, this, this, tracker, passthrough_texture_);
+      manager, this, this, tracker, std::move(gl_textures));
 }
 
 std::unique_ptr<OverlayImageRepresentation> PbufferImageBacking::ProduceOverlay(
@@ -128,9 +130,12 @@
         context_state->gr_context()->threadSafeProxy(), &backend_texture);
     cached_promise_texture_ = SkPromiseImageTexture::Make(backend_texture);
   }
+
+  std::vector<sk_sp<SkPromiseImageTexture>> promise_textures = {
+      cached_promise_texture_};
   return std::make_unique<SkiaGLCommonRepresentation>(
       manager, this, gl_client, std::move(context_state),
-      cached_promise_texture_, tracker);
+      std::move(promise_textures), tracker);
 }
 
 bool PbufferImageBacking::GLTextureImageRepresentationBeginAccess(
@@ -142,10 +147,4 @@
 void PbufferImageBacking::GLTextureImageRepresentationEndAccess(bool readonly) {
 }
 
-void PbufferImageBacking::GLTextureImageRepresentationRelease(
-    bool has_context) {
-  // No action needed: This class retains the passed-in texture for its
-  // lifetime, and releases it in its destructor.
-}
-
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image/pbuffer_image_backing.h b/gpu/command_buffer/service/shared_image/pbuffer_image_backing.h
index ae0a799a..5e753fc9 100644
--- a/gpu/command_buffer/service/shared_image/pbuffer_image_backing.h
+++ b/gpu/command_buffer/service/shared_image/pbuffer_image_backing.h
@@ -66,7 +66,6 @@
   // GLTextureImageRepresentationClient:
   bool GLTextureImageRepresentationBeginAccess(bool readonly) override;
   void GLTextureImageRepresentationEndAccess(bool readonly) override;
-  void GLTextureImageRepresentationRelease(bool have_context) override;
 
   base::ScopedClosureRunner on_destruction_closure_runner_;
 
diff --git a/gpu/command_buffer/service/shared_image/shared_image_representation.cc b/gpu/command_buffer/service/shared_image/shared_image_representation.cc
index e27c48ba..082c1537 100644
--- a/gpu/command_buffer/service/shared_image/shared_image_representation.cc
+++ b/gpu/command_buffer/service/shared_image/shared_image_representation.cc
@@ -45,6 +45,14 @@
   }
 }
 
+size_t SharedImageRepresentation::NumPlanesExpected() const {
+  if (format().PrefersExternalSampler()) {
+    return 1;
+  }
+
+  return static_cast<size_t>(format().NumberOfPlanes());
+}
+
 std::unique_ptr<GLTextureImageRepresentation::ScopedAccess>
 GLTextureImageRepresentationBase::BeginScopedAccess(
     GLenum mode,
diff --git a/gpu/command_buffer/service/shared_image/shared_image_representation.h b/gpu/command_buffer/service/shared_image/shared_image_representation.h
index 6662c51b..7bb5f01 100644
--- a/gpu/command_buffer/service/shared_image/shared_image_representation.h
+++ b/gpu/command_buffer/service/shared_image/shared_image_representation.h
@@ -109,6 +109,9 @@
     backing_->OnContextLost();
   }
 
+  // Returns the number of image planes expected based on the backing format.
+  size_t NumPlanesExpected() const;
+
  protected:
   SharedImageManager* manager() const { return manager_; }
   SharedImageBacking* backing() const { return backing_; }
diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json
index c7ae55f..0d717d6 100644
--- a/gpu/config/gpu_driver_bug_list.json
+++ b/gpu/config/gpu_driver_bug_list.json
@@ -4175,7 +4175,7 @@
       "vendor_id": "0x1002",
       "driver_version": {
         "op": "<=",
-        "value": "26.20.15002.61 "
+        "value": "26.20.15002.61"
       },
       "features": [
         "disable_media_foundation_clear_playback"
diff --git a/gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap.cc b/gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap.cc
index 689ea2d..b8d25d6 100644
--- a/gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap.cc
+++ b/gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap.cc
@@ -4,8 +4,6 @@
 
 #include "gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap.h"
 
-#include <vulkan/vulkan.h>
-
 #include <utility>
 
 #include "base/functional/bind.h"
diff --git a/headless/BUILD.gn b/headless/BUILD.gn
index 59b6351e..2cfeea1c 100644
--- a/headless/BUILD.gn
+++ b/headless/BUILD.gn
@@ -303,8 +303,6 @@
 # Code that is not needed in a renderer process.
 component("headless_non_renderer") {
   sources = [
-    "app/headless_shell_switches.cc",
-    "app/headless_shell_switches.h",
     "lib/browser/directory_enumerator.cc",
     "lib/browser/directory_enumerator.h",
     "lib/browser/headless_browser_context_impl.cc",
@@ -351,6 +349,7 @@
     "lib/headless_content_main_delegate.h",
     "lib/renderer/headless_content_renderer_client.cc",
     "lib/renderer/headless_content_renderer_client.h",
+    "lib/switches.cc",
     "lib/utility/headless_content_utility_client.cc",
     "lib/utility/headless_content_utility_client.h",
     "public/headless_browser.cc",
@@ -363,6 +362,7 @@
     "public/headless_web_contents.h",
     "public/internal/message_dispatcher.h",
     "public/internal/value_conversions.h",
+    "public/switches.h",
     "public/util/error_reporter.cc",
     "public/util/error_reporter.h",
     "public/util/user_agent.cc",
@@ -834,7 +834,6 @@
       "app/headless_shell.cc",
       "app/headless_shell_command_line.cc",
       "app/headless_shell_command_line.h",
-      "app/headless_shell_switches.h",
       "public/headless_shell.h",
     ]
     deps = [
@@ -873,7 +872,6 @@
     "app/headless_shell.cc",
     "app/headless_shell_command_line.cc",
     "app/headless_shell_command_line.h",
-    "app/headless_shell_switches.h",
     "public/headless_shell.h",
   ]
   defines = []
diff --git a/headless/app/headless_shell.cc b/headless/app/headless_shell.cc
index e80272e..7f7aa7a 100644
--- a/headless/app/headless_shell.cc
+++ b/headless/app/headless_shell.cc
@@ -18,13 +18,13 @@
 #include "content/public/app/content_main.h"
 #include "content/public/common/content_switches.h"
 #include "headless/app/headless_shell_command_line.h"
-#include "headless/app/headless_shell_switches.h"
 #include "headless/lib/browser/headless_browser_impl.h"
 #include "headless/lib/browser/headless_web_contents_impl.h"
 #include "headless/lib/headless_content_main_delegate.h"
 #include "headless/public/headless_browser.h"
 #include "headless/public/headless_browser_context.h"
 #include "headless/public/headless_web_contents.h"
+#include "headless/public/switches.h"
 #include "net/base/filename_util.h"
 #include "url/gurl.h"
 
diff --git a/headless/app/headless_shell_command_line.cc b/headless/app/headless_shell_command_line.cc
index 751941f..4fc8f1f 100644
--- a/headless/app/headless_shell_command_line.cc
+++ b/headless/app/headless_shell_command_line.cc
@@ -11,7 +11,7 @@
 #include "cc/base/switches.h"
 #include "components/viz/common/switches.h"
 #include "content/public/common/content_switches.h"
-#include "headless/app/headless_shell_switches.h"
+#include "headless/public/switches.h"
 #include "net/base/host_port_pair.h"
 #include "net/base/ip_address.h"
 #include "net/http/http_util.h"
diff --git a/headless/lib/browser/headless_browser_impl.cc b/headless/lib/browser/headless_browser_impl.cc
index 67b3f19..6d7716c 100644
--- a/headless/lib/browser/headless_browser_impl.cc
+++ b/headless/lib/browser/headless_browser_impl.cc
@@ -8,24 +8,16 @@
 #include <utility>
 #include <vector>
 
-#include "base/command_line.h"
-#include "base/functional/callback_helpers.h"
+#include "base/functional/callback.h"
 #include "base/memory/ptr_util.h"
-#include "base/run_loop.h"
 #include "base/task/single_thread_task_runner.h"
-#include "content/public/app/content_main.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/devtools_agent_host.h"
-#include "content/public/common/content_switches.h"
-#include "headless/app/headless_shell_switches.h"
 #include "headless/lib/browser/headless_browser_context_impl.h"
 #include "headless/lib/browser/headless_browser_main_parts.h"
 #include "headless/lib/browser/headless_devtools_agent_host_client.h"
 #include "headless/lib/browser/headless_web_contents_impl.h"
-#include "net/http/http_util.h"
-#include "services/network/public/cpp/network_switches.h"
-#include "ui/events/devices/device_data_manager.h"
 
 namespace headless {
 
diff --git a/headless/lib/browser/headless_browser_main_parts.cc b/headless/lib/browser/headless_browser_main_parts.cc
index dd498f9..81546ff4 100644
--- a/headless/lib/browser/headless_browser_main_parts.cc
+++ b/headless/lib/browser/headless_browser_main_parts.cc
@@ -10,12 +10,12 @@
 #include "base/run_loop.h"
 #include "build/build_config.h"
 #include "content/public/common/result_codes.h"
-#include "headless/app/headless_shell_switches.h"
 #include "headless/lib/browser/headless_browser_context_impl.h"
 #include "headless/lib/browser/headless_browser_impl.h"
 #include "headless/lib/browser/headless_devtools.h"
 #include "headless/lib/browser/headless_screen.h"
 #include "headless/lib/browser/headless_select_file_dialog_factory.h"
+#include "headless/public/switches.h"
 
 #if defined(HEADLESS_USE_PREFS)
 #include "components/os_crypt/os_crypt.h"  // nogncheck
diff --git a/headless/lib/browser/headless_browser_main_parts_linux.cc b/headless/lib/browser/headless_browser_main_parts_linux.cc
index 46dba0d..0a4264c2 100644
--- a/headless/lib/browser/headless_browser_main_parts_linux.cc
+++ b/headless/lib/browser/headless_browser_main_parts_linux.cc
@@ -14,7 +14,7 @@
 #include "components/os_crypt/os_crypt.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
-#include "headless/app/headless_shell_switches.h"
+#include "headless/public/switches.h"
 #endif
 
 namespace headless {
diff --git a/headless/lib/browser/headless_content_browser_client.cc b/headless/lib/browser/headless_content_browser_client.cc
index 0ee7177..31fba53 100644
--- a/headless/lib/browser/headless_content_browser_client.cc
+++ b/headless/lib/browser/headless_content_browser_client.cc
@@ -28,11 +28,11 @@
 #include "content/public/browser/storage_partition.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/content_switches.h"
-#include "headless/app/headless_shell_switches.h"
 #include "headless/lib/browser/headless_browser_context_impl.h"
 #include "headless/lib/browser/headless_browser_impl.h"
 #include "headless/lib/browser/headless_browser_main_parts.h"
 #include "headless/lib/browser/headless_devtools_manager_delegate.h"
+#include "headless/public/switches.h"
 #include "mojo/public/cpp/bindings/binder_map.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/receiver_set.h"
diff --git a/headless/lib/browser/headless_request_context_manager.cc b/headless/lib/browser/headless_request_context_manager.cc
index 20d2f72..84965071 100644
--- a/headless/lib/browser/headless_request_context_manager.cc
+++ b/headless/lib/browser/headless_request_context_manager.cc
@@ -12,8 +12,8 @@
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/network_service_instance.h"
 #include "content/public/browser/resource_context.h"
-#include "headless/app/headless_shell_switches.h"
 #include "headless/lib/browser/headless_browser_context_options.h"
+#include "headless/public/switches.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "net/http/http_auth_preferences.h"
 #include "net/proxy_resolution/proxy_config_service.h"
diff --git a/headless/lib/renderer/headless_print_render_frame_helper_delegate.cc b/headless/lib/renderer/headless_print_render_frame_helper_delegate.cc
index 1174580..8987b3e 100644
--- a/headless/lib/renderer/headless_print_render_frame_helper_delegate.cc
+++ b/headless/lib/renderer/headless_print_render_frame_helper_delegate.cc
@@ -4,7 +4,7 @@
 
 #include "headless/lib/renderer/headless_print_render_frame_helper_delegate.h"
 #include "base/command_line.h"
-#include "headless/app/headless_shell_switches.h"
+#include "headless/public/switches.h"
 #include "third_party/blink/public/web/web_element.h"
 
 namespace headless {
diff --git a/headless/app/headless_shell_switches.cc b/headless/lib/switches.cc
similarity index 98%
rename from headless/app/headless_shell_switches.cc
rename to headless/lib/switches.cc
index 87cd096..64b26af9 100644
--- a/headless/app/headless_shell_switches.cc
+++ b/headless/lib/switches.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 "headless/app/headless_shell_switches.h"
+#include "headless/public/switches.h"
 
 namespace headless {
 namespace switches {
diff --git a/headless/app/headless_shell_switches.h b/headless/public/switches.h
similarity index 90%
rename from headless/app/headless_shell_switches.h
rename to headless/public/switches.h
index f848da5..a23b1c1 100644
--- a/headless/app/headless_shell_switches.h
+++ b/headless/public/switches.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 HEADLESS_APP_HEADLESS_SHELL_SWITCHES_H_
-#define HEADLESS_APP_HEADLESS_SHELL_SWITCHES_H_
+#ifndef HEADLESS_PUBLIC_SWITCHES_H_
+#define HEADLESS_PUBLIC_SWITCHES_H_
 
 #include "headless/public/headless_export.h"
 
@@ -35,4 +35,4 @@
 }  // namespace switches
 }  // namespace headless
 
-#endif  // HEADLESS_APP_HEADLESS_SHELL_SWITCHES_H_
+#endif  // HEADLESS_PUBLIC_SWITCHES_H_
diff --git a/headless/test/headless_browser_browsertest.cc b/headless/test/headless_browser_browsertest.cc
index a5074899..06d6b48 100644
--- a/headless/test/headless_browser_browsertest.cc
+++ b/headless/test/headless_browser_browsertest.cc
@@ -28,13 +28,13 @@
 #include "content/public/common/url_constants.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/no_renderer_crashes_assertion.h"
-#include "headless/app/headless_shell_switches.h"
 #include "headless/lib/browser/headless_browser_context_impl.h"
 #include "headless/lib/browser/headless_browser_impl.h"
 #include "headless/lib/browser/headless_select_file_dialog_factory.h"
 #include "headless/lib/browser/headless_web_contents_impl.h"
 #include "headless/public/headless_browser.h"
 #include "headless/public/headless_web_contents.h"
+#include "headless/public/switches.h"
 #include "headless/test/headless_browser_test.h"
 #include "headless/test/headless_browser_test_utils.h"
 #include "net/base/net_errors.h"
diff --git a/headless/test/headless_browser_context_browsertest.cc b/headless/test/headless_browser_context_browsertest.cc
index c24a4d9..7f24026 100644
--- a/headless/test/headless_browser_context_browsertest.cc
+++ b/headless/test/headless_browser_context_browsertest.cc
@@ -15,7 +15,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test.h"
-#include "headless/app/headless_shell_switches.h"
 #include "headless/lib/browser/headless_web_contents_impl.h"
 #include "headless/public/headless_browser.h"
 #include "headless/public/headless_browser_context.h"
diff --git a/headless/test/headless_printtopdf_browsertest.cc b/headless/test/headless_printtopdf_browsertest.cc
index 6f5f9d6..b1ceb60 100644
--- a/headless/test/headless_printtopdf_browsertest.cc
+++ b/headless/test/headless_printtopdf_browsertest.cc
@@ -16,7 +16,7 @@
 #include "base/test/values_test_util.h"
 #include "base/values.h"
 #include "content/public/test/browser_test.h"
-#include "headless/app/headless_shell_switches.h"
+#include "headless/public/switches.h"
 #include "headless/test/headless_browser_test.h"
 #include "headless/test/headless_browser_test_utils.h"
 #include "headless/test/headless_devtooled_browsertest.h"
diff --git a/headless/test/headless_protocol_browsertest.cc b/headless/test/headless_protocol_browsertest.cc
index 9ce1277..406dc08 100644
--- a/headless/test/headless_protocol_browsertest.cc
+++ b/headless/test/headless_protocol_browsertest.cc
@@ -14,8 +14,8 @@
 #include "base/path_service.h"
 #include "build/build_config.h"
 #include "content/public/common/content_switches.h"
-#include "headless/app/headless_shell_switches.h"
 #include "headless/lib/browser/headless_web_contents_impl.h"
+#include "headless/public/switches.h"
 #include "headless/test/headless_browser_test_utils.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "services/network/public/cpp/network_switches.h"
diff --git a/headless/test/headless_web_contents_browsertest.cc b/headless/test/headless_web_contents_browsertest.cc
index 071cbe4..629ebbfb 100644
--- a/headless/test/headless_web_contents_browsertest.cc
+++ b/headless/test/headless_web_contents_browsertest.cc
@@ -21,7 +21,6 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test.h"
-#include "headless/app/headless_shell_switches.h"
 #include "headless/lib/browser/headless_web_contents_impl.h"
 #include "headless/public/headless_browser.h"
 #include "headless/public/headless_web_contents.h"
diff --git a/infra/config/generated/builders/ci/lacros-arm64-generic-rel-skylab-fyi/properties.json b/infra/config/generated/builders/ci/lacros-arm64-generic-rel-skylab-fyi/properties.json
index 2ede1cc..a2245b2 100644
--- a/infra/config/generated/builders/ci/lacros-arm64-generic-rel-skylab-fyi/properties.json
+++ b/infra/config/generated/builders/ci/lacros-arm64-generic-rel-skylab-fyi/properties.json
@@ -24,7 +24,7 @@
                 ],
                 "target_bits": 64,
                 "target_cros_boards": [
-                  "kevin"
+                  "kevin:jacuzzi"
                 ],
                 "target_platform": "chromeos"
               },
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg
index 387e8b769..679ebb39 100644
--- a/infra/config/generated/luci/luci-milo.cfg
+++ b/infra/config/generated/luci/luci-milo.cfg
@@ -1787,6 +1787,11 @@
     short_name: "ast"
   }
   builders {
+    name: "buildbucket/luci.chrome.ci/fuchsia-perf-nsn"
+    category: "gardener|hardware|perf"
+    short_name: "nsn"
+  }
+  builders {
     name: "buildbucket/luci.chrome.ci/fuchsia-perf-shk"
     category: "gardener|hardware|perf"
     short_name: "sher"
@@ -1847,11 +1852,6 @@
     short_name: "atl"
   }
   builders {
-    name: "buildbucket/luci.chrome.ci/fuchsia-perf-nsn"
-    category: "fyi|hardware|perf"
-    short_name: "nsn"
-  }
-  builders {
     name: "buildbucket/luci.chrome.ci/fuchsia-perf-nuc-fyi"
     category: "fyi|hardware|perf"
     short_name: "nuc"
diff --git a/infra/config/subprojects/chromium/ci.star b/infra/config/subprojects/chromium/ci.star
index 6a76a4c..e181f6bc 100644
--- a/infra/config/subprojects/chromium/ci.star
+++ b/infra/config/subprojects/chromium/ci.star
@@ -134,7 +134,7 @@
     ("fuchsia-perf-ast", "gardener|hardware|perf", "ast"),
     ("fuchsia-perf-atlas-fyi", "fyi|hardware|perf", "atl"),
     ("fuchsia-perf-fyi", "fyi|hardware|perf", "ast"),
-    ("fuchsia-perf-nsn", "fyi|hardware|perf", "nsn"),
+    ("fuchsia-perf-nsn", "gardener|hardware|perf", "nsn"),
     ("fuchsia-perf-nuc-fyi", "fyi|hardware|perf", "nuc"),
     ("fuchsia-perf-shk", "gardener|hardware|perf", "sher"),
     ("fuchsia-x64", "gardener|p/chrome|x64", "rel"),
diff --git a/infra/config/subprojects/chromium/ci/chromium.fyi.star b/infra/config/subprojects/chromium/ci/chromium.fyi.star
index 8ba58b74..84fd82df 100644
--- a/infra/config/subprojects/chromium/ci/chromium.fyi.star
+++ b/infra/config/subprojects/chromium/ci/chromium.fyi.star
@@ -352,7 +352,7 @@
             apply_configs = ["mb", "mb_no_luci_auth"],
             target_bits = 64,
             target_platform = "chromeos",
-            target_cros_boards = "kevin",
+            target_cros_boards = "kevin:jacuzzi",
             cros_boards_with_qemu_images = "arm64-generic",
         ),
         build_gs_bucket = "chromium-fyi-archive",
diff --git a/ios/build/tools/setup-gn.py b/ios/build/tools/setup-gn.py
index 905e5a5a..4d81ee5f 100755
--- a/ios/build/tools/setup-gn.py
+++ b/ios/build/tools/setup-gn.py
@@ -19,7 +19,7 @@
 
 SUPPORTED_TARGETS = ('iphoneos', 'iphonesimulator', 'maccatalyst')
 SUPPORTED_CONFIGS = ('Debug', 'Release', 'Profile', 'Official')
-ADDITIONAL_FILE_ROOTS = ('//ios', '//ios_internal', '//docs')
+ADDITIONAL_FILE_ROOTS = ('//ios', '//ios_internal', '//docs', '//components')
 
 # Pattern matching lines from ~/.lldbinit that must not be copied to the
 # generated .lldbinit file. They match what the user were told to add to
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd
index 1812916..e50e012c 100644
--- a/ios/chrome/app/strings/ios_strings.grd
+++ b/ios/chrome/app/strings/ios_strings.grd
@@ -1522,6 +1522,9 @@
       <message name="IDS_IOS_NEW_INCOGNITO_TAB_PAGE" desc="Label for text saying the user is on the new Incognito tab page">
         New Incognito Tab Page
       </message>
+      <message name="IDS_IOS_NEW_ITEM_ACCESSIBILITY_HINT" desc="Accessibility hint spoken by VoiceOver to let the user know there is a new item. This string will be appended to an existing accesibility label when the UI is showing a little blue dot to attract the user's attention. For example, the label 'Default Browser' would become 'Default Browser, new item', which is why the string is not capitalized at its start. [iOS/iPadOS only]">
+        new item
+      </message>
       <message name="IDS_IOS_NEW_TAB_IPH_PROMOTION_TEXT" desc="Text for the New Tab Tip in-product help promotion, explaining that new tabs can be added and switched between. [iOS only]" meaning="The user has never created a new tab, and a bubble is displayed pointing to the tab switcher to inform users how to create tabs and switch between them.">
         Add tabs and switch between pages
       </message>
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_NEW_ITEM_ACCESSIBILITY_HINT.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_NEW_ITEM_ACCESSIBILITY_HINT.png.sha1
new file mode 100644
index 0000000..96e6b37
--- /dev/null
+++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_NEW_ITEM_ACCESSIBILITY_HINT.png.sha1
@@ -0,0 +1 @@
+2d5faabb74825aa2909414377ef60dc7e34e7924
\ No newline at end of file
diff --git a/ios/chrome/browser/ui/bookmarks/BUILD.gn b/ios/chrome/browser/ui/bookmarks/BUILD.gn
index 9eb8cd8..bc248407 100644
--- a/ios/chrome/browser/ui/bookmarks/BUILD.gn
+++ b/ios/chrome/browser/ui/bookmarks/BUILD.gn
@@ -64,6 +64,7 @@
     "//ios/chrome/browser/ui/authentication/cells",
     "//ios/chrome/browser/ui/authentication/enterprise:enterprise_utils",
     "//ios/chrome/browser/ui/bookmarks/cells",
+    "//ios/chrome/browser/ui/bookmarks/editor",
     "//ios/chrome/browser/ui/commands",
     "//ios/chrome/browser/ui/default_promo:utils",
     "//ios/chrome/browser/ui/elements",
@@ -134,8 +135,6 @@
 source_set("bookmarks_ui") {
   configs += [ "//build/config/compiler:enable_arc" ]
   sources = [
-    "bookmark_edit_view_controller.h",
-    "bookmark_edit_view_controller.mm",
     "bookmark_folder_editor_view_controller.h",
     "bookmark_folder_editor_view_controller.mm",
     "bookmark_folder_view_controller.h",
@@ -185,7 +184,6 @@
   configs += [ "//build/config/compiler:enable_arc" ]
   testonly = true
   sources = [
-    "bookmark_edit_view_controller_unittest.mm",
     "bookmark_home_view_controller_unittest.mm",
     "bookmark_path_cache_unittest.mm",
     "bookmark_utils_ios_unittest.mm",
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 088c8d15..76937505 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm
@@ -34,7 +34,6 @@
 #import "ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h"
 #import "ios/chrome/browser/ui/authentication/cells/signin_promo_view_configurator.h"
 #import "ios/chrome/browser/ui/authentication/cells/table_view_signin_promo_item.h"
-#import "ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_folder_view_controller.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_home_consumer.h"
@@ -49,6 +48,7 @@
 #import "ios/chrome/browser/ui/bookmarks/cells/bookmark_folder_item.h"
 #import "ios/chrome/browser/ui/bookmarks/cells/bookmark_home_node_item.h"
 #import "ios/chrome/browser/ui/bookmarks/cells/bookmark_table_cell_title_edit_delegate.h"
+#import "ios/chrome/browser/ui/bookmarks/editor/bookmarks_editor_view_controller.h"
 #import "ios/chrome/browser/ui/commands/application_commands.h"
 #import "ios/chrome/browser/ui/commands/command_dispatcher.h"
 #import "ios/chrome/browser/ui/commands/snackbar_commands.h"
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm
index 2a644b5..3285e6a 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm
@@ -22,7 +22,6 @@
 #import "ios/chrome/browser/main/browser.h"
 #import "ios/chrome/browser/metrics/new_tab_page_uma.h"
 #import "ios/chrome/browser/tabs/tab_title_util.h"
-#import "ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_folder_view_controller.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.h"
@@ -33,6 +32,7 @@
 #import "ios/chrome/browser/ui/bookmarks/bookmark_path_cache.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_transitioning_delegate.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h"
+#import "ios/chrome/browser/ui/bookmarks/editor/bookmarks_editor_view_controller.h"
 #import "ios/chrome/browser/ui/commands/application_commands.h"
 #import "ios/chrome/browser/ui/commands/command_dispatcher.h"
 #import "ios/chrome/browser/ui/commands/snackbar_commands.h"
@@ -72,7 +72,7 @@
 }  // namespace
 
 @interface BookmarkInteractionController () <
-    BookmarkEditViewControllerDelegate,
+    BookmarksEditorViewControllerDelegate,
     BookmarkFolderEditorViewControllerDelegate,
     BookmarkFolderViewControllerDelegate,
     BookmarkHomeViewControllerDelegate,
@@ -113,7 +113,7 @@
 
 // A reference to the potentially presented single bookmark editor. This will be
 // non-nil when `currentPresentedState` is BOOKMARK_EDITOR.
-@property(nonatomic, strong) BookmarkEditViewController* bookmarkEditor;
+@property(nonatomic, strong) BookmarksEditorViewController* bookmarkEditor;
 
 // A reference to the potentially presented folder editor. This will be non-nil
 // when `currentPresentedState` is FOLDER_EDITOR.
@@ -327,9 +327,9 @@
       editorController = nil;
   if (node->type() == BookmarkNode::URL) {
     self.currentPresentedState = PresentedState::BOOKMARK_EDITOR;
-    BookmarkEditViewController* bookmarkEditor =
-        [[BookmarkEditViewController alloc] initWithBookmark:node
-                                                     browser:_browser];
+    BookmarksEditorViewController* bookmarkEditor =
+        [[BookmarksEditorViewController alloc] initWithBookmark:node
+                                                        browser:_browser];
     bookmarkEditor.delegate = self;
     bookmarkEditor.snackbarCommandsHandler = self.snackbarCommandsHandler;
     self.bookmarkEditor = bookmarkEditor;
@@ -480,19 +480,20 @@
           bookmark_utils_ios::kBookmarksSnackbarCategory];
 }
 
-#pragma mark - BookmarkEditViewControllerDelegate
+#pragma mark - BookmarksEditorViewControllerDelegate
 
-- (BOOL)bookmarkEditor:(BookmarkEditViewController*)controller
+- (BOOL)bookmarkEditor:(BookmarksEditorViewController*)controller
     shoudDeleteAllOccurencesOfBookmark:(const BookmarkNode*)bookmark {
   return YES;
 }
 
-- (void)bookmarkEditorWantsDismissal:(BookmarkEditViewController*)controller {
+- (void)bookmarkEditorWantsDismissal:
+    (BookmarksEditorViewController*)controller {
   [self dismissBookmarkEditorAnimated:YES];
 }
 
 - (void)bookmarkEditorWillCommitTitleOrUrlChange:
-    (BookmarkEditViewController*)controller {
+    (BookmarksEditorViewController*)controller {
   [self.delegate bookmarkInteractionControllerWillCommitTitleOrUrlChange:self];
 }
 
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_mediator.mm b/ios/chrome/browser/ui/bookmarks/bookmark_mediator.mm
index 81235b1..03ff1a4 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_mediator.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_mediator.mm
@@ -75,9 +75,7 @@
   base::RecordAction(base::UserMetricsAction("BookmarkAdded"));
   LogLikelyInterestedDefaultBrowserUserActivity(DefaultPromoTypeAllTabs);
 
-  const BookmarkNode* defaultFolder =
-      [[self class] folderForNewBookmarksInBookmarkModel:_bookmarkModel
-                                                   prefs:_prefs];
+  const BookmarkNode* defaultFolder = [self folderForNewBookmarks];
   _bookmarkModel->AddNewURL(defaultFolder, defaultFolder->children().size(),
                             base::SysNSStringToUTF16(title), URL);
 
@@ -125,16 +123,14 @@
 
 #pragma mark - Private
 
-+ (const BookmarkNode*)
-    folderForNewBookmarksInBookmarkModel:(bookmarks::BookmarkModel*)bookmarks
-                                   prefs:(PrefService*)prefs {
-  const BookmarkNode* defaultFolder = bookmarks->mobile_node();
-  int64_t node_id = prefs->GetInt64(prefs::kIosBookmarkFolderDefault);
+- (const BookmarkNode*)folderForNewBookmarks {
+  const BookmarkNode* defaultFolder = _bookmarkModel->mobile_node();
+  int64_t node_id = _prefs->GetInt64(prefs::kIosBookmarkFolderDefault);
   if (node_id == kLastUsedFolderNone) {
     node_id = defaultFolder->id();
   }
   const BookmarkNode* result =
-      bookmarks::GetBookmarkNodeByID(bookmarks, node_id);
+      bookmarks::GetBookmarkNodeByID(_bookmarkModel, node_id);
 
   if (result) {
     return result;
diff --git a/ios/chrome/browser/ui/bookmarks/editor/BUILD.gn b/ios/chrome/browser/ui/bookmarks/editor/BUILD.gn
index 3f2a3de..8d520051 100644
--- a/ios/chrome/browser/ui/bookmarks/editor/BUILD.gn
+++ b/ios/chrome/browser/ui/bookmarks/editor/BUILD.gn
@@ -8,11 +8,66 @@
     "bookmarks_editor_coordinator.h",
     "bookmarks_editor_coordinator.mm",
     "bookmarks_editor_coordinator_delegate.h",
+    "bookmarks_editor_view_controller.h",
+    "bookmarks_editor_view_controller.mm",
   ]
   deps = [
-    "//ios/chrome/browser/ui/bookmarks/folder_chooser",
-    "//ios/chrome/browser/ui/bookmarks/folder_editor",
+    "//base",
+    "//base:i18n",
+    "//components/bookmarks/browser",
+    "//components/strings",
+    "//components/url_formatter",
+    "//ios/chrome/app/strings",
+    "//ios/chrome/browser/bookmarks",
+    "//ios/chrome/browser/browser_state",
+    "//ios/chrome/browser/flags:system_flags",
+    "//ios/chrome/browser/main:public",
+    "//ios/chrome/browser/ui/alert_coordinator",
+    "//ios/chrome/browser/ui/bookmarks:bookmarks_ui",
+    "//ios/chrome/browser/ui/bookmarks:constants",
+    "//ios/chrome/browser/ui/bookmarks:core",
+    "//ios/chrome/browser/ui/bookmarks/cells",
+    "//ios/chrome/browser/ui/commands",
     "//ios/chrome/browser/ui/coordinators:chrome_coordinators",
-    "//url",
+    "//ios/chrome/browser/ui/icons",
+    "//ios/chrome/browser/ui/image_util",
+    "//ios/chrome/browser/ui/keyboard",
+    "//ios/chrome/browser/ui/table_view",
+    "//ios/chrome/browser/ui/table_view:presentation",
+    "//ios/chrome/browser/ui/table_view:styler",
+    "//ios/chrome/browser/ui/table_view:utils",
+    "//ios/chrome/browser/ui/table_view:views",
+    "//ios/chrome/common/ui/util",
+    "//ui/base",
+  ]
+}
+
+source_set("unit_tests") {
+  configs += [ "//build/config/compiler:enable_arc" ]
+  testonly = true
+  sources = [ "bookmarks_editor_view_controller_unittest.mm" ]
+  deps = [
+    ":editor",
+    "//base",
+    "//base/test:test_support",
+    "//components/bookmarks/browser",
+    "//components/bookmarks/test",
+    "//components/sync_preferences:test_support",
+    "//ios/chrome/browser/bookmarks",
+    "//ios/chrome/browser/bookmarks:test_support",
+    "//ios/chrome/browser/bookmarks:test_support",
+    "//ios/chrome/browser/browser_state:test_support",
+    "//ios/chrome/browser/flags:system_flags",
+    "//ios/chrome/browser/main:public",
+    "//ios/chrome/browser/main:test_support",
+    "//ios/chrome/browser/ui/bookmarks:bookmarks",
+    "//ios/chrome/browser/ui/bookmarks:bookmarks_ui",
+    "//ios/chrome/browser/ui/bookmarks:constants",
+    "//ios/chrome/browser/ui/bookmarks:core",
+    "//ios/chrome/browser/ui/commands",
+    "//ios/chrome/test:test_support",
+    "//ios/web/public/test",
+    "//testing/gtest",
+    "//third_party/ocmock:ocmock",
   ]
 }
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.h b/ios/chrome/browser/ui/bookmarks/editor/bookmarks_editor_view_controller.h
similarity index 75%
rename from ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.h
rename to ios/chrome/browser/ui/bookmarks/editor/bookmarks_editor_view_controller.h
index 5054d77..4b55944 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.h
+++ b/ios/chrome/browser/ui/bookmarks/editor/bookmarks_editor_view_controller.h
@@ -1,15 +1,15 @@
 // Copyright 2014 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
-#ifndef IOS_CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_EDIT_VIEW_CONTROLLER_H_
-#define IOS_CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_EDIT_VIEW_CONTROLLER_H_
+#ifndef IOS_CHROME_BROWSER_UI_BOOKMARKS_EDITOR_BOOKMARKS_EDITOR_VIEW_CONTROLLER_H_
+#define IOS_CHROME_BROWSER_UI_BOOKMARKS_EDITOR_BOOKMARKS_EDITOR_VIEW_CONTROLLER_H_
 
 #import <UIKit/UIKit.h>
 
 #import "ios/chrome/browser/ui/keyboard/key_command_actions.h"
 #import "ios/chrome/browser/ui/table_view/chrome_table_view_controller.h"
 
-@class BookmarkEditViewController;
+@class BookmarksEditorViewController;
 @class BookmarkFolderViewController;
 class Browser;
 @protocol SnackbarCommands;
@@ -18,7 +18,7 @@
 class BookmarkNode;
 }  // namespace bookmarks
 
-@protocol BookmarkEditViewControllerDelegate
+@protocol BookmarksEditorViewControllerDelegate
 
 // Called when the edited bookmark is set for deletion.
 // If the delegate returns `YES`, all nodes matching the URL of `bookmark` will
@@ -26,15 +26,15 @@
 // If the delegate returns `NO`, only `bookmark` will be deleted.
 // If the delegate doesn't implement this method, the default behavior is to
 // delete all nodes matching the URL of `bookmark`.
-- (BOOL)bookmarkEditor:(BookmarkEditViewController*)controller
+- (BOOL)bookmarkEditor:(BookmarksEditorViewController*)controller
     shoudDeleteAllOccurencesOfBookmark:(const bookmarks::BookmarkNode*)bookmark;
 
 // Called when the controller should be dismissed.
-- (void)bookmarkEditorWantsDismissal:(BookmarkEditViewController*)controller;
+- (void)bookmarkEditorWantsDismissal:(BookmarksEditorViewController*)controller;
 
 // Called when the controller is going to commit the title or URL change.
 - (void)bookmarkEditorWillCommitTitleOrUrlChange:
-    (BookmarkEditViewController*)controller;
+    (BookmarksEditorViewController*)controller;
 
 @end
 
@@ -44,11 +44,11 @@
 // This view controller will also monitor bookmark model change events and react
 // accordingly depending on whether the bookmark and folder it is editing
 // changes underneath it.
-@interface BookmarkEditViewController
+@interface BookmarksEditorViewController
     : ChromeTableViewController <KeyCommandActions,
                                  UIAdaptivePresentationControllerDelegate>
 
-@property(nonatomic, weak) id<BookmarkEditViewControllerDelegate> delegate;
+@property(nonatomic, weak) id<BookmarksEditorViewControllerDelegate> delegate;
 
 // Snackbar commands handler.
 @property(nonatomic, weak) id<SnackbarCommands> snackbarCommandsHandler;
@@ -65,4 +65,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_EDIT_VIEW_CONTROLLER_H_
+#endif  // IOS_CHROME_BROWSER_UI_BOOKMARKS_EDITOR_BOOKMARKS_EDITOR_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm b/ios/chrome/browser/ui/bookmarks/editor/bookmarks_editor_view_controller.mm
similarity index 98%
rename from ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm
rename to ios/chrome/browser/ui/bookmarks/editor/bookmarks_editor_view_controller.mm
index 57cba94..41d467f 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm
+++ b/ios/chrome/browser/ui/bookmarks/editor/bookmarks_editor_view_controller.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.h"
+#import "ios/chrome/browser/ui/bookmarks/editor/bookmarks_editor_view_controller.h"
 
 #import <memory>
 #import <set>
@@ -80,9 +80,10 @@
 const CGFloat kEstimatedTableSectionFooterHeight = 40;
 }  // namespace
 
-@interface BookmarkEditViewController () <BookmarkFolderViewControllerDelegate,
-                                          BookmarkModelBridgeObserver,
-                                          BookmarkTextFieldItemDelegate> {
+@interface BookmarksEditorViewController () <
+    BookmarkFolderViewControllerDelegate,
+    BookmarkModelBridgeObserver,
+    BookmarkTextFieldItemDelegate> {
   // Flag to ignore bookmark model changes notifications.
   BOOL _ignoresBookmarkModelChanges;
 
@@ -161,7 +162,7 @@
 
 #pragma mark
 
-@implementation BookmarkEditViewController
+@implementation BookmarksEditorViewController
 
 @synthesize bookmark = _bookmark;
 @synthesize bookmarkModel = _bookmarkModel;
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller_unittest.mm b/ios/chrome/browser/ui/bookmarks/editor/bookmarks_editor_view_controller_unittest.mm
similarity index 60%
rename from ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller_unittest.mm
rename to ios/chrome/browser/ui/bookmarks/editor/bookmarks_editor_view_controller_unittest.mm
index 7ddb13f..2745b66 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/bookmarks/editor/bookmarks_editor_view_controller_unittest.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.h"
+#import "ios/chrome/browser/ui/bookmarks/editor/bookmarks_editor_view_controller.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -15,38 +15,38 @@
 
 namespace {
 
-using BookmarkEditViewControllerTest = BookmarkIOSUnitTestSupport;
+using BookmarksEditorViewControllerTest = BookmarkIOSUnitTestSupport;
 
 // Checks that the view controller can become the first responder. This is
 // needed to correctly register key commands.
-TEST_F(BookmarkEditViewControllerTest, CanBecomeFirstResponder) {
+TEST_F(BookmarksEditorViewControllerTest, CanBecomeFirstResponder) {
   const bookmarks::BookmarkNode* bookmark =
       AddBookmark(bookmark_model_->mobile_node(), @"Some Bookmark");
-  BookmarkEditViewController* controller =
-      [[BookmarkEditViewController alloc] initWithBookmark:bookmark
-                                                   browser:browser_.get()];
+  BookmarksEditorViewController* controller =
+      [[BookmarksEditorViewController alloc] initWithBookmark:bookmark
+                                                      browser:browser_.get()];
 
   EXPECT_TRUE(controller.canBecomeFirstResponder);
 }
 
 // Checks that key commands are registered.
-TEST_F(BookmarkEditViewControllerTest, KeyCommands) {
+TEST_F(BookmarksEditorViewControllerTest, KeyCommands) {
   const bookmarks::BookmarkNode* bookmark =
       AddBookmark(bookmark_model_->mobile_node(), @"Some Bookmark");
-  BookmarkEditViewController* controller =
-      [[BookmarkEditViewController alloc] initWithBookmark:bookmark
-                                                   browser:browser_.get()];
+  BookmarksEditorViewController* controller =
+      [[BookmarksEditorViewController alloc] initWithBookmark:bookmark
+                                                      browser:browser_.get()];
 
   EXPECT_GT(controller.keyCommands.count, 0u);
 }
 
 // Checks that metrics are correctly reported.
-TEST_F(BookmarkEditViewControllerTest, Metrics) {
+TEST_F(BookmarksEditorViewControllerTest, Metrics) {
   const bookmarks::BookmarkNode* bookmark =
       AddBookmark(bookmark_model_->mobile_node(), @"Some Bookmark");
-  BookmarkEditViewController* controller =
-      [[BookmarkEditViewController alloc] initWithBookmark:bookmark
-                                                   browser:browser_.get()];
+  BookmarksEditorViewController* controller =
+      [[BookmarksEditorViewController alloc] initWithBookmark:bookmark
+                                                      browser:browser_.get()];
   base::UserActionTester user_action_tester;
   std::string user_action = "MobileKeyCommandClose";
   ASSERT_EQ(user_action_tester.GetActionCount(user_action), 0);
diff --git a/ios/chrome/browser/ui/infobars/translate_infobar_egtest.mm b/ios/chrome/browser/ui/infobars/translate_infobar_egtest.mm
index 8cf653c..0ba8ac8c 100644
--- a/ios/chrome/browser/ui/infobars/translate_infobar_egtest.mm
+++ b/ios/chrome/browser/ui/infobars/translate_infobar_egtest.mm
@@ -12,6 +12,7 @@
 #import "base/test/ios/wait_util.h"
 #import "components/translate/core/browser/translate_pref_names.h"
 #import "components/translate/core/common/translate_constants.h"
+#import "components/translate/core/common/translate_util.h"
 #import "ios/chrome/browser/translate/translate_app_interface.h"
 #import "ios/chrome/browser/ui/badges/badge_constants.h"
 #import "ios/chrome/browser/ui/infobars/banners/infobar_banner_constants.h"
@@ -246,6 +247,19 @@
 
 @implementation TranslateInfobarTestCase
 
+- (AppLaunchConfiguration)appConfigurationForTestCase {
+  AppLaunchConfiguration config;
+  if ([self isRunningTest:@selector
+            (testLanguageDetectionDisabledWithForceTranslate)]) {
+    config.features_enabled.push_back(translate::kIOSForceTranslateEnabled);
+  }
+  if ([self isRunningTest:@selector
+            (testLanguageDetectionDisabledWithoutForceTranslate)]) {
+    config.features_disabled.push_back(translate::kIOSForceTranslateEnabled);
+  }
+  return config;
+}
+
 - (void)setUp {
   [super setUp];
 
@@ -478,9 +492,43 @@
   [self assertContentLanguage:@"" htmlRootLanguage:@"fr" adoptedLanguage:@"fr"];
 }
 
-// Tests that language detection is not performed when translate is disabled.
-// TODO(crbug.com/1406208): A language is detected.
-- (void)DISABLED_testLanguageDetectionDisabled {
+// Tests that language detection is performed but no infobar is triggered when
+// translate is disabled but force translate is on.
+- (void)testLanguageDetectionDisabledWithForceTranslate {
+  std::unique_ptr<web::DataResponseProvider> provider(new TestResponseProvider);
+  web::test::SetUpHttpServer(std::move(provider));
+
+  // Load a page with French text.
+  GURL URL = web::test::HttpServer::MakeUrl(
+      base::StringPrintf("http://%s", kFrenchPagePath));
+
+  // Disable translate.
+  [ChromeEarlGreyAppInterface
+      setBoolValue:NO
+       forUserPref:base::SysUTF8ToNSString(
+                       translate::prefs::kOfferTranslateEnabled)];
+
+  // Open some webpage.
+  [ChromeEarlGrey loadURL:URL];
+  // Wait to be sure language detection has time to happen and benner to appear.
+  base::test::ios::SpinRunLoopWithMaxDelay(base::Seconds(2));
+
+  // Check that language has been detected.
+  GREYAssert([self waitForLanguageDetection], @"Language not detected");
+  // Check Banner was not presented.
+  GREYAssertFalse([self isBeforeTranslateBannerVisible],
+                  @"Before Translate banner was found");
+
+  // Enable translate.
+  [ChromeEarlGreyAppInterface
+      setBoolValue:YES
+       forUserPref:base::SysUTF8ToNSString(
+                       translate::prefs::kOfferTranslateEnabled)];
+}
+
+// Tests that language detection is not performed when translate is disabled
+// with force translate disabled.
+- (void)testLanguageDetectionDisabledWithoutForceTranslate {
   const GURL URL = web::test::HttpServer::MakeUrl(
       "http://scenarioLanguageDetectionDisabled");
   std::map<GURL, std::string> responses;
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_destination_view.swift b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_destination_view.swift
index fb3992a..6337fd2 100644
--- a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_destination_view.swift
+++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_destination_view.swift
@@ -49,9 +49,6 @@
 
     /// The width of the new label badge.
     static let newLabelBadgeWidth: CGFloat = 20
-
-    /// The width of the badge border.
-    static let badgeBorderWidth: CGFloat = 2
   }
 
   /// The destination for this view.
@@ -159,14 +156,11 @@
       .overlay {
         if destination.badge == .blueDot {
           Circle()
-            .strokeBorder(
-              backgroundColor(configuration: configuration), lineWidth: Dimensions.badgeBorderWidth
-            )
-            // Pad the color circle by 0.5, otherwise the color shows up faintly
-            // around the border.
-            .background(Circle().foregroundColor(.blue600).padding(0.5))
+            .background(Circle().foregroundColor(.blue600).padding(0))
             .frame(width: Dimensions.badgeWidth, height: Dimensions.badgeWidth)
-            .offset(x: Dimensions.iconWidth / 2, y: -Dimensions.iconWidth / 2)
+            .offset(
+              x: Dimensions.iconWidth - (Dimensions.badgeWidth / 2),
+              y: -Dimensions.iconWidth + (Dimensions.badgeWidth / 2))
         } else if destination.badge == .newLabel {
           Image(systemName: "seal.fill")
             .resizable()
@@ -287,7 +281,9 @@
   var accessibilityLabel: String {
     return [
       destination.name,
-      destination.badge != .none
+      destination.badge == .blueDot
+        ? L10NUtils.stringWithFixup(forMessageId: IDS_IOS_NEW_ITEM_ACCESSIBILITY_HINT) : nil,
+      destination.badge == .newLabel
         ? L10NUtils.stringWithFixup(forMessageId: IDS_IOS_TOOLS_MENU_CELL_NEW_FEATURE_BADGE) : nil,
     ].compactMap { $0 }.joined(separator: ", ")
   }
diff --git a/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm b/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm
index de4d6960b..74f3548 100644
--- a/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm
@@ -76,6 +76,7 @@
   ItemTypeURLWithThirdRowText,
   ItemTypeURLWithBadgeImage,
   ItemTypeTextSettingsDetail,
+  ItemTypeTableViewWithBlueDot,
   ItemTypeLinkFooter,
   ItemTypeDetailText,
   ItemTypeMultiDetailText,
@@ -141,6 +142,16 @@
   symbolItem.iconCornerRadius = 7;
   [model addItem:symbolItem toSectionWithIdentifier:SectionIdentifierText];
 
+  TableViewDetailIconItem* tableViewBlueDotItem =
+      [[TableViewDetailIconItem alloc]
+          initWithType:ItemTypeTableViewWithBlueDot];
+  tableViewBlueDotItem.showNotificationDot = YES;
+  tableViewBlueDotItem.text = @"I have a blue dot badge!";
+  tableViewBlueDotItem.iconImage =
+      [UIImage imageNamed:@"default_browser_world"];
+  [model addItem:tableViewBlueDotItem
+      toSectionWithIdentifier:SectionIdentifierText];
+
   TableViewTextItem* textItem =
       [[TableViewTextItem alloc] initWithType:ItemTypeText];
   textItem.text = @"Simple Text Cell";
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_context_menu/tab_item.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_context_menu/tab_item.h
index 1a20dfa..94e4fb8 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_context_menu/tab_item.h
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_context_menu/tab_item.h
@@ -12,9 +12,9 @@
 // Model object representing details about a tab item.
 @interface TabItem : NSObject
 
-// Create an item with `title`, and `url`.
+// Create an item with `title`, and `URL`.
 - (instancetype)initWithTitle:(NSString*)title
-                          url:(GURL)URL NS_DESIGNATED_INITIALIZER;
+                          URL:(GURL)URL NS_DESIGNATED_INITIALIZER;
 
 - (instancetype)init NS_UNAVAILABLE;
 
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_context_menu/tab_item.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_context_menu/tab_item.mm
index fba0cfd..5da3b40 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_context_menu/tab_item.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_context_menu/tab_item.mm
@@ -12,7 +12,7 @@
 
 @implementation TabItem
 
-- (instancetype)initWithTitle:(NSString*)title url:(GURL)URL {
+- (instancetype)initWithTitle:(NSString*)title URL:(GURL)URL {
   if ((self = [super init])) {
     _title = title;
     _URL = URL;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_utils.mm b/ios/chrome/browser/ui/tab_switcher/tab_utils.mm
index 259ab1d..80784ba4d 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_utils.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_utils.mm
@@ -99,7 +99,7 @@
 
   TabItem* item =
       [[TabItem alloc] initWithTitle:tab_util::GetTabTitle(web_state)
-                                 url:web_state->GetVisibleURL()];
+                                 URL:web_state->GetVisibleURL()];
   return item;
 }
 
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_detail_icon_item.h b/ios/chrome/browser/ui/table_view/cells/table_view_detail_icon_item.h
index f9bad43f..62e7a76b 100644
--- a/ios/chrome/browser/ui/table_view/cells/table_view_detail_icon_item.h
+++ b/ios/chrome/browser/ui/table_view/cells/table_view_detail_icon_item.h
@@ -12,7 +12,7 @@
 // TableViewDetailIconItem is a model class that uses TableViewDetailIconCell.
 @interface TableViewDetailIconItem : TableViewItem
 
-// The leading icon.  If empty, no icon will be shown.
+// The leading icon. If empty, no icon will be shown.
 @property(nonatomic, copy) UIImage* iconImage;
 
 // The background color of the icon.
@@ -36,6 +36,11 @@
 // Defaults to UILayoutConstraintAxisHorizontal.
 @property(nonatomic, assign) UILayoutConstraintAxis textLayoutConstraintAxis;
 
+// If set to YES, a kBlue600Color dot will be shown in the Cell. The
+// notification dot is only supported when `textLayoutConstraintAxis` is set to
+// `UILayoutConstraintAxisHorizontal`.
+@property(nonatomic, assign) BOOL showNotificationDot;
+
 @end
 
 // TableViewDetailIconCell implements an TableViewCell subclass containing an
@@ -46,7 +51,7 @@
 // the cell. Labels are truncated as needed to fit in the cell.
 @interface TableViewDetailIconCell : TableViewCell
 
-// UILabels corresponding to `text` and `detailText` from the item.
+// UILabel corresponding to `text` from the item.
 @property(nonatomic, readonly, strong) UILabel* textLabel;
 
 // The layout constraint axis of the text labels within the cell. Defaults
@@ -67,6 +72,12 @@
 // text.
 - (void)setDetailText:(NSString*)detailText;
 
+// Sets whether or not to show the notification dot. The notification dot is
+// only supported when `textLayoutConstraintAxis` is set to
+// `UILayoutConstraintAxisHorizontal`. If the notification dot is activated
+// while the axis is vertical, the app will crash through DCHECK.
+- (void)setShowNotificationDot:(BOOL)showNotificationDot;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_TABLE_VIEW_CELLS_TABLE_VIEW_DETAIL_ICON_ITEM_H_
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_detail_icon_item.mm b/ios/chrome/browser/ui/table_view/cells/table_view_detail_icon_item.mm
index a31c6399..354040e 100644
--- a/ios/chrome/browser/ui/table_view/cells/table_view_detail_icon_item.mm
+++ b/ios/chrome/browser/ui/table_view/cells/table_view_detail_icon_item.mm
@@ -11,6 +11,8 @@
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/table_view/table_view_cells_constants.h"
 #import "ios/chrome/common/ui/util/constraints_ui_util.h"
+#import "ios/chrome/grit/ios_strings.h"
+#import "ui/base/l10n/l10n_util_mac.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -25,6 +27,16 @@
 // Minimum cell height when the cell has 2 lines.
 constexpr CGFloat kChromeTableViewTwoLinesCellHeight = 58.f;
 
+// kDotSize represents the size of the dot (i.e. its height and width).
+constexpr CGFloat kDotSize = 10.f;
+
+// kMarginAroundDot represents the amount of space before and after the dot,
+// between itself and the surrounding UILabels `text` and `detailText`.
+constexpr CGFloat kMarginAroundDot = 5.f;
+
+// kBlueDotColor is the specific blue used for the blue dot notification badge.
+constexpr NSString* kBlueDotColor = @"blue_600_color";
+
 }  // namespace
 
 @implementation TableViewDetailIconItem
@@ -50,6 +62,7 @@
       backgroundColor:self.iconBackgroundColor
          cornerRadius:self.iconCornerRadius];
   [cell setTextLayoutConstraintAxis:self.textLayoutConstraintAxis];
+  [cell setShowNotificationDot:self.showNotificationDot];
 }
 
 @end
@@ -69,6 +82,8 @@
 @property(nonatomic, strong) NSLayoutConstraint* textWidthConstraint;
 // Detail text. Can be nil if no text is set.
 @property(nonatomic, strong) UILabel* detailTextLabel;
+// View representing the colored notification dot wrapper.
+@property(nonatomic, strong) UIView* notificationDotUIView;
 
 @end
 
@@ -238,6 +253,16 @@
   }
 }
 
+- (void)setShowNotificationDot:(BOOL)showNotificationDot {
+  if (showNotificationDot) {
+    if (!self.notificationDotUIView) {
+      [self createNotificationDot];
+    }
+  } else {
+    [self removeNotificationDot];
+  }
+}
+
 #pragma mark - UIView
 
 - (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection {
@@ -261,6 +286,7 @@
   [self setTextLayoutConstraintAxis:UILayoutConstraintAxisHorizontal];
   [self setIconImage:nil tintColor:nil backgroundColor:nil cornerRadius:0];
   [self setDetailText:nil];
+  [self setShowNotificationDot:NO];
 }
 
 #pragma mark - Private
@@ -300,6 +326,63 @@
   self.textLayoutConstraintAxis = UILayoutConstraintAxisHorizontal;
 }
 
+// Creates the UIView for the dot and adds it to the UI with the needed
+// constraints.
+- (void)createNotificationDot {
+  if (self.notificationDotUIView) {
+    return;
+  }
+
+  // Since we're inserting the dot at index 1, this DCHECK checks to make sure
+  // the main text's UILabel subview is there.
+  DCHECK(self.textStackView.subviews.count > 0);
+
+  // Since only the horizontal axis is supported for the notification dot, make
+  // sure we currently have the right axis.
+  DCHECK([self textLayoutConstraintAxis] == UILayoutConstraintAxisHorizontal);
+
+  // Make sure the notification dot is always snug next to the main text.
+  [self.textLabel setContentHuggingPriority:UILayoutPriorityDefaultHigh
+                                    forAxis:UILayoutConstraintAxisHorizontal];
+
+  self.notificationDotUIView = [[UIView alloc] init];
+  UIView* dotUIView = [[UIView alloc] init];
+
+  self.notificationDotUIView.translatesAutoresizingMaskIntoConstraints = NO;
+  dotUIView.translatesAutoresizingMaskIntoConstraints = NO;
+
+  [self.notificationDotUIView addSubview:dotUIView];
+  [self.textStackView insertArrangedSubview:self.notificationDotUIView
+                                    atIndex:1];
+  [self.textStackView setCustomSpacing:kMarginAroundDot
+                             afterView:self.textLabel];
+  [self.textStackView setCustomSpacing:kMarginAroundDot
+                             afterView:self.notificationDotUIView];
+
+  [NSLayoutConstraint activateConstraints:@[
+    [self.notificationDotUIView.widthAnchor
+        constraintGreaterThanOrEqualToConstant:kDotSize],
+    [dotUIView.widthAnchor constraintEqualToConstant:kDotSize],
+    [dotUIView.heightAnchor constraintEqualToConstant:kDotSize],
+    [dotUIView.centerYAnchor
+        constraintEqualToAnchor:self.textLabel.centerYAnchor],
+  ]];
+
+  dotUIView.layer.cornerRadius = kDotSize / 2;
+  dotUIView.backgroundColor = [UIColor colorNamed:kBlueDotColor];
+}
+
+// Removes the notification dot's UIView from the UI.
+- (void)removeNotificationDot {
+  if (!self.notificationDotUIView) {
+    return;
+  }
+
+  [self.textStackView setCustomSpacing:0 afterView:self.textLabel];
+  [self.notificationDotUIView removeFromSuperview];
+  self.notificationDotUIView = nil;
+}
+
 // Updates the cell such as it is layouted correctly with regard to the
 // preferred content size category, if it is an
 // `accessibilityContentSizeCategory` or not.
@@ -337,6 +420,11 @@
 }
 
 - (NSString*)accessibilityLabel {
+  if (self.notificationDotUIView) {
+    return [NSString stringWithFormat:@"%@, %@", self.textLabel.text,
+                                      l10n_util::GetNSString(
+                                          IDS_IOS_NEW_ITEM_ACCESSIBILITY_HINT)];
+  }
   return self.textLabel.text;
 }
 
@@ -345,6 +433,12 @@
 }
 
 - (NSArray<NSString*>*)accessibilityUserInputLabels {
+  if (self.notificationDotUIView) {
+    return @[ [NSString
+        stringWithFormat:@"%@, %@", self.textLabel.text,
+                         l10n_util::GetNSString(
+                             IDS_IOS_NEW_ITEM_ACCESSIBILITY_HINT)] ];
+  }
   return @[ self.textLabel.text ];
 }
 
diff --git a/ios/chrome/test/providers/BUILD.gn b/ios/chrome/test/providers/BUILD.gn
index 7381f0c..ce04afe 100644
--- a/ios/chrome/test/providers/BUILD.gn
+++ b/ios/chrome/test/providers/BUILD.gn
@@ -11,6 +11,7 @@
     "//ios/chrome/test/providers/branded_images",
     "//ios/chrome/test/providers/context_menu",
     "//ios/chrome/test/providers/discover_feed",
+    "//ios/chrome/test/providers/find_in_page",
     "//ios/chrome/test/providers/follow",
     "//ios/chrome/test/providers/font",
     "//ios/chrome/test/providers/fullscreen",
diff --git a/ios/chrome/test/providers/find_in_page/BUILD.gn b/ios/chrome/test/providers/find_in_page/BUILD.gn
new file mode 100644
index 0000000..7f43d5c
--- /dev/null
+++ b/ios/chrome/test/providers/find_in_page/BUILD.gn
@@ -0,0 +1,14 @@
+# Copyright 2023 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("find_in_page") {
+  testonly = true
+  configs += [ "//build/config/compiler:enable_arc" ]
+  sources = [ "test_find_in_page.mm" ]
+  frameworks = [ "Foundation.framework" ]
+  deps = [
+    "//base",
+    "//ios/public/provider/chrome/browser/find_in_page:find_in_page_api",
+  ]
+}
diff --git a/ios/chrome/test/providers/find_in_page/test_find_in_page.mm b/ios/chrome/test/providers/find_in_page/test_find_in_page.mm
new file mode 100644
index 0000000..819669f
--- /dev/null
+++ b/ios/chrome/test/providers/find_in_page/test_find_in_page.mm
@@ -0,0 +1,50 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <Foundation/Foundation.h>
+
+#import "base/notreached.h"
+#import "ios/public/provider/chrome/browser/find_in_page/find_in_page_api.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace ios {
+namespace provider {
+
+bool IsNativeFindInPageWithSystemFindPanel() {
+  return false;
+}
+
+bool IsNativeFindInPageWithChromeFindBar() {
+  return false;
+}
+
+bool IsNativeFindInPageEnabled() {
+  return false;
+}
+
+id<UITextSearching> GetSearchableObjectForWebState(web::WebState* web_state)
+    API_AVAILABLE(ios(16)) {
+  // `IsNativeFindInPageWithChromeFindBar` is unconditionally `false` so this
+  // should never be reached.
+  NOTREACHED();
+  return nil;
+}
+
+void StartTextSearchInWebState(web::WebState* web_state) {
+  // `IsNativeFindInPageWithChromeFindBar` is unconditionally `false` so this
+  // should never be reached.
+  NOTREACHED();
+}
+
+void StopTextSearchInWebState(web::WebState* web_state) {
+  // `IsNativeFindInPageWithChromeFindBar` is unconditionally `false` so this
+  // should never be reached.
+  NOTREACHED();
+}
+
+}  // namespace provider
+}  // namespace ios
diff --git a/media/fuchsia/audio/fake_audio_device_enumerator_local_component.cc b/media/fuchsia/audio/fake_audio_device_enumerator_local_component.cc
index 46f75c0..488f9159 100644
--- a/media/fuchsia/audio/fake_audio_device_enumerator_local_component.cc
+++ b/media/fuchsia/audio/fake_audio_device_enumerator_local_component.cc
@@ -41,11 +41,8 @@
   FAIL() << "Unexpected call to unimplemented method \"" << name << "\"";
 }
 
-void FakeAudioDeviceEnumeratorLocalComponent::Start(
-    std::unique_ptr<::component_testing::LocalComponentHandles> mock_handles) {
-  handles_ = std::move(mock_handles);
-  ASSERT_EQ(handles_->outgoing()->AddPublicService(bindings_.GetHandler(this)),
-            ZX_OK);
+void FakeAudioDeviceEnumeratorLocalComponent::OnStart() {
+  ASSERT_EQ(outgoing()->AddPublicService(bindings_.GetHandler(this)), ZX_OK);
 }
 
 }  // namespace media
diff --git a/media/fuchsia/audio/fake_audio_device_enumerator_local_component.h b/media/fuchsia/audio/fake_audio_device_enumerator_local_component.h
index 3de6fee..b005319 100644
--- a/media/fuchsia/audio/fake_audio_device_enumerator_local_component.h
+++ b/media/fuchsia/audio/fake_audio_device_enumerator_local_component.h
@@ -9,7 +9,6 @@
 #include <lib/fidl/cpp/binding_set.h>
 #include <lib/sys/component/cpp/testing/realm_builder.h>
 
-#include <memory>
 #include <string>
 
 namespace media {
@@ -17,7 +16,7 @@
 // A fake AudioDeviceEnumerator for use in tests that use RealmBuilder.
 class FakeAudioDeviceEnumeratorLocalComponent final
     : public ::fuchsia::media::testing::AudioDeviceEnumerator_TestBase,
-      public ::component_testing::LocalComponent {
+      public ::component_testing::LocalComponentImpl {
  public:
   FakeAudioDeviceEnumeratorLocalComponent();
   FakeAudioDeviceEnumeratorLocalComponent(
@@ -30,13 +29,11 @@
   void GetDevices(GetDevicesCallback callback) override;
   void NotImplemented_(const std::string& name) override;
 
-  // ::component_testing::LocalComponent:
-  void Start(std::unique_ptr<::component_testing::LocalComponentHandles>
-                 mock_handles) override;
+  // ::component_testing::LocalComponentImpl:
+  void OnStart() override;
 
  private:
   fidl::BindingSet<::fuchsia::media::AudioDeviceEnumerator> bindings_;
-  std::unique_ptr<::component_testing::LocalComponentHandles> handles_;
 };
 
 }  // namespace media
diff --git a/media/gpu/chromeos/BUILD.gn b/media/gpu/chromeos/BUILD.gn
index 7cfe1cf..acf6239c 100644
--- a/media/gpu/chromeos/BUILD.gn
+++ b/media/gpu/chromeos/BUILD.gn
@@ -211,6 +211,7 @@
     "//build:chromeos_buildflags",
     "//media:test_support",
     "//media/gpu:buildflags",
+    "//media/gpu:video_frame_mapper_common",
     "//media/gpu/test:frame_file_writer",
     "//media/gpu/test:frame_validator",
     "//media/gpu/test:helpers",
@@ -218,5 +219,8 @@
     "//media/gpu/test:video_test_environment",
     "//mojo/core/embedder",
     "//testing/gtest",
+    "//third_party/libyuv",
+    "//ui/gl",
+    "//ui/gl:test_support",
   ]
 }
diff --git a/media/gpu/chromeos/image_processor_factory.cc b/media/gpu/chromeos/image_processor_factory.cc
index b24fbf5..483d837 100644
--- a/media/gpu/chromeos/image_processor_factory.cc
+++ b/media/gpu/chromeos/image_processor_factory.cc
@@ -307,4 +307,34 @@
   return nullptr;
 }
 
+#if BUILDFLAG(USE_V4L2_CODEC)
+std::unique_ptr<ImageProcessor>
+ImageProcessorFactory::CreateLibYUVImageProcessorWithInputCandidatesForTesting(
+    const std::vector<ImageProcessor::PixelLayoutCandidate>& input_candidates,
+    const gfx::Rect& input_visible_rect,
+    const gfx::Size& output_size,
+    size_t num_buffers,
+    scoped_refptr<base::SequencedTaskRunner> client_task_runner,
+    PickFormatCB out_format_picker,
+    ImageProcessor::ErrorCB error_cb) {
+  return CreateLibYUVImageProcessorWithInputCandidates(
+      input_candidates, input_visible_rect, output_size, client_task_runner,
+      out_format_picker, error_cb);
+}
+
+std::unique_ptr<ImageProcessor>
+ImageProcessorFactory::CreateGLImageProcessorWithInputCandidatesForTesting(
+    const std::vector<ImageProcessor::PixelLayoutCandidate>& input_candidates,
+    const gfx::Rect& input_visible_rect,
+    const gfx::Size& output_size,
+    size_t num_buffers,
+    scoped_refptr<base::SequencedTaskRunner> client_task_runner,
+    PickFormatCB out_format_picker,
+    ImageProcessor::ErrorCB error_cb) {
+  return CreateGLImageProcessorWithInputCandidates(
+      input_candidates, input_visible_rect, output_size, client_task_runner,
+      out_format_picker, error_cb);
+}
+#endif
+
 }  // namespace media
diff --git a/media/gpu/chromeos/image_processor_factory.h b/media/gpu/chromeos/image_processor_factory.h
index 9160c93..1498192 100644
--- a/media/gpu/chromeos/image_processor_factory.h
+++ b/media/gpu/chromeos/image_processor_factory.h
@@ -61,6 +61,28 @@
       PickFormatCB out_format_picker,
       ImageProcessor::ErrorCB error_cb);
 
+#if BUILDFLAG(USE_V4L2_CODEC)
+  static std::unique_ptr<ImageProcessor>
+  CreateLibYUVImageProcessorWithInputCandidatesForTesting(
+      const std::vector<ImageProcessor::PixelLayoutCandidate>& input_candidates,
+      const gfx::Rect& input_visible_rect,
+      const gfx::Size& output_size,
+      size_t num_buffers,
+      scoped_refptr<base::SequencedTaskRunner> client_task_runner,
+      PickFormatCB out_format_picker,
+      ImageProcessor::ErrorCB error_cb);
+
+  static std::unique_ptr<ImageProcessor>
+  CreateGLImageProcessorWithInputCandidatesForTesting(
+      const std::vector<ImageProcessor::PixelLayoutCandidate>& input_candidates,
+      const gfx::Rect& input_visible_rect,
+      const gfx::Size& output_size,
+      size_t num_buffers,
+      scoped_refptr<base::SequencedTaskRunner> client_task_runner,
+      PickFormatCB out_format_picker,
+      ImageProcessor::ErrorCB error_cb);
+#endif
+
   ImageProcessorFactory() = delete;
   ImageProcessorFactory(const ImageProcessorFactory&) = delete;
   ImageProcessorFactory& operator=(const ImageProcessorFactory&) = delete;
diff --git a/media/gpu/chromeos/image_processor_test.cc b/media/gpu/chromeos/image_processor_test.cc
index 52e5a41f..814ceb7 100644
--- a/media/gpu/chromeos/image_processor_test.cc
+++ b/media/gpu/chromeos/image_processor_test.cc
@@ -2,14 +2,20 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <sys/mman.h>
+
 #include <memory>
 #include <string>
 #include <tuple>
+#include <vector>
 
+#include "base/bits.h"
 #include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/hash/md5.h"
+#include "base/rand_util.h"
+#include "base/run_loop.h"
 #include "base/test/launcher/unit_test_launcher.h"
 #include "base/test/test_suite.h"
 #include "build/build_config.h"
@@ -19,15 +25,24 @@
 #include "media/base/video_types.h"
 #include "media/gpu/chromeos/fourcc.h"
 #include "media/gpu/chromeos/image_processor.h"
+#include "media/gpu/chromeos/image_processor_backend.h"
+#include "media/gpu/chromeos/image_processor_factory.h"
+#include "media/gpu/chromeos/platform_video_frame_utils.h"
 #include "media/gpu/test/image.h"
 #include "media/gpu/test/image_processor/image_processor_client.h"
 #include "media/gpu/test/video_frame_file_writer.h"
 #include "media/gpu/test/video_frame_helpers.h"
 #include "media/gpu/test/video_frame_validator.h"
 #include "media/gpu/test/video_test_environment.h"
+#include "media/gpu/video_frame_mapper.h"
+#include "media/gpu/video_frame_mapper_factory.h"
 #include "mojo/core/embedder/embedder.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/geometry/size.h"
+#include "ui/gl/test/gl_surface_test_support.h"
+
+#define MM21_TILE_WIDTH 32
+#define MM21_TILE_HEIGHT 16
 
 namespace media {
 namespace {
@@ -132,6 +147,125 @@
 }
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
+#if BUILDFLAG(USE_V4L2_CODEC)
+scoped_refptr<VideoFrame> CreateNV12Frame(const gfx::Size& size,
+                                          VideoFrame::StorageType type) {
+  const gfx::Rect visible_rect(size);
+  constexpr base::TimeDelta kNullTimestamp;
+  if (type == VideoFrame::STORAGE_GPU_MEMORY_BUFFER) {
+    return CreateGpuMemoryBufferVideoFrame(
+        VideoPixelFormat::PIXEL_FORMAT_NV12, size, visible_rect, size,
+        kNullTimestamp, gfx::BufferUsage::SCANOUT_CPU_READ_WRITE);
+  } else {
+    DCHECK(type == VideoFrame::STORAGE_DMABUFS);
+    return CreatePlatformVideoFrame(VideoPixelFormat::PIXEL_FORMAT_NV12, size,
+                                    visible_rect, size, kNullTimestamp,
+                                    gfx::BufferUsage::SCANOUT_CPU_READ_WRITE);
+  }
+}
+
+scoped_refptr<VideoFrame> CreateRandomMM21Frame(const gfx::Size& size,
+                                                VideoFrame::StorageType type) {
+  DCHECK(size.width() == base::bits::AlignUp(size.width(), MM21_TILE_WIDTH));
+  DCHECK(size.height() == base::bits::AlignUp(size.height(), MM21_TILE_HEIGHT));
+
+  scoped_refptr<VideoFrame> ret = CreateNV12Frame(size, type);
+  if (!ret) {
+    LOG(ERROR) << "Failed to create MM21 frame";
+    return nullptr;
+  }
+
+  std::unique_ptr<VideoFrameMapper> frame_mapper =
+      VideoFrameMapperFactory::CreateMapper(
+          VideoPixelFormat::PIXEL_FORMAT_NV12, type,
+          /*force_linear_buffer_mapper=*/true);
+  scoped_refptr<VideoFrame> mapped_ret =
+      frame_mapper->Map(ret, PROT_READ | PROT_WRITE);
+  if (!mapped_ret) {
+    LOG(ERROR) << "Unable to map MM21 frame";
+    return nullptr;
+  }
+
+  uint8_t* y_plane = mapped_ret->GetWritableVisibleData(VideoFrame::kYPlane);
+  uint8_t* uv_plane = mapped_ret->GetWritableVisibleData(VideoFrame::kUVPlane);
+  for (int row = 0; row < size.height(); row++) {
+    for (int col = 0; col < size.width(); col++) {
+      y_plane[col] = base::RandInt(/*min=*/0, /*max=*/255);
+      if (row % 2 == 0) {
+        uv_plane[col] = base::RandInt(/*min=*/0, /*max=*/255);
+      }
+    }
+    y_plane += mapped_ret->stride(VideoFrame::kYPlane);
+    if (row % 2 == 0) {
+      uv_plane += mapped_ret->stride(VideoFrame::kUVPlane);
+    }
+  }
+
+  return ret;
+}
+
+bool CompareNV12VideoFrames(scoped_refptr<VideoFrame> test_frame,
+                            scoped_refptr<VideoFrame> golden_frame) {
+  if (test_frame->coded_size() != golden_frame->coded_size() ||
+      test_frame->visible_rect() != golden_frame->visible_rect() ||
+      test_frame->format() != VideoPixelFormat::PIXEL_FORMAT_NV12 ||
+      golden_frame->format() != VideoPixelFormat::PIXEL_FORMAT_NV12) {
+    return false;
+  }
+
+  std::unique_ptr<VideoFrameMapper> test_frame_mapper =
+      VideoFrameMapperFactory::CreateMapper(
+          VideoPixelFormat::PIXEL_FORMAT_NV12, test_frame->storage_type(),
+          /*force_linear_buffer_mapper=*/true);
+  std::unique_ptr<VideoFrameMapper> golden_frame_mapper =
+      VideoFrameMapperFactory::CreateMapper(
+          VideoPixelFormat::PIXEL_FORMAT_NV12, golden_frame->storage_type(),
+          /*force_linear_buffer_mapper=*/true);
+  scoped_refptr<VideoFrame> mapped_test_frame =
+      test_frame_mapper->Map(test_frame, PROT_READ | PROT_WRITE);
+  if (!mapped_test_frame) {
+    LOG(ERROR) << "Unable to map test frame";
+    return false;
+  }
+  scoped_refptr<VideoFrame> mapped_golden_frame =
+      golden_frame_mapper->Map(golden_frame, PROT_READ | PROT_WRITE);
+  if (!mapped_golden_frame) {
+    LOG(ERROR) << "Unable to map golden frame";
+    return false;
+  }
+
+  const uint8_t* test_y_plane =
+      mapped_test_frame->visible_data(VideoFrame::kYPlane);
+  const uint8_t* test_uv_plane =
+      mapped_test_frame->visible_data(VideoFrame::kUVPlane);
+  const uint8_t* golden_y_plane =
+      mapped_golden_frame->visible_data(VideoFrame::kYPlane);
+  const uint8_t* golden_uv_plane =
+      mapped_golden_frame->visible_data(VideoFrame::kUVPlane);
+  for (int y = 0; y < test_frame->coded_size().height(); y++) {
+    for (int x = 0; x < test_frame->coded_size().width(); x++) {
+      if (test_y_plane[x] != golden_y_plane[x]) {
+        return false;
+      }
+
+      if (y % 2 == 0) {
+        if (test_uv_plane[x] != golden_uv_plane[x]) {
+          return false;
+        }
+      }
+    }
+    test_y_plane += mapped_test_frame->stride(VideoFrame::kYPlane);
+    golden_y_plane += mapped_golden_frame->stride(VideoFrame::kYPlane);
+    if (y % 2 == 0) {
+      test_uv_plane += mapped_test_frame->stride(VideoFrame::kUVPlane);
+      golden_uv_plane += mapped_golden_frame->stride(VideoFrame::kUVPlane);
+    }
+  }
+
+  return true;
+}
+#endif
+
 class ImageProcessorParamTest
     : public ::testing::Test,
       public ::testing::WithParamInterface<
@@ -421,6 +555,102 @@
 // TODO(hiroh): Add more tests.
 // MEM->DMABUF (V4L2VideoEncodeAccelerator),
 #endif
+
+#if BUILDFLAG(USE_V4L2_CODEC)
+TEST(ImageProcessorBackendTest, CompareLibYUVAndGLBackendsForMM21Image) {
+  gl::GLSurfaceTestSupport::InitializeOneOffImplementation(
+      gl::GLImplementationParts(gl::kGLImplementationEGLGLES2),
+      /*fallback_to_software_gl=*/false);
+
+  constexpr gfx::Size kTestImageSize(1920, 1088);
+  constexpr gfx::Rect kTestImageVisibleRect(kTestImageSize);
+  const ImageProcessor::PixelLayoutCandidate candidate = {Fourcc(Fourcc::MM21),
+                                                          kTestImageSize};
+  std::vector<ImageProcessor::PixelLayoutCandidate> candidates = {candidate};
+
+  auto client_task_runner = base::SequencedTaskRunner::GetCurrentDefault();
+  base::RunLoop run_loop;
+  base::RepeatingClosure quit_closure = run_loop.QuitClosure();
+  bool image_processor_error = false;
+  ImageProcessor::ErrorCB error_cb = base::BindRepeating(
+      [](scoped_refptr<base::SequencedTaskRunner> client_task_runner,
+         base::RepeatingClosure quit_closure, bool* image_processor_error) {
+        CHECK(client_task_runner->RunsTasksInCurrentSequence());
+        *image_processor_error = true;
+        quit_closure.Run();
+      },
+      client_task_runner, quit_closure, &image_processor_error);
+  ImageProcessorFactory::PickFormatCB pick_format_cb = base::BindRepeating(
+      [](const std::vector<Fourcc>&, absl::optional<Fourcc>) {
+        return absl::make_optional<Fourcc>(Fourcc::NV12);
+      });
+
+  std::unique_ptr<ImageProcessor> libyuv_image_processor =
+      ImageProcessorFactory::
+          CreateLibYUVImageProcessorWithInputCandidatesForTesting(
+              candidates, kTestImageVisibleRect, kTestImageSize,
+              /*num_buffers=*/1, client_task_runner, pick_format_cb, error_cb);
+  ASSERT_TRUE(libyuv_image_processor)
+      << "Error creating LibYUV image processor";
+  std::unique_ptr<ImageProcessor> gl_image_processor = ImageProcessorFactory::
+      CreateGLImageProcessorWithInputCandidatesForTesting(
+          candidates, kTestImageVisibleRect, kTestImageSize, /*num_buffers=*/1,
+          client_task_runner, pick_format_cb, error_cb);
+  ASSERT_TRUE(gl_image_processor) << "Error creating GLImageProcessor";
+
+  scoped_refptr<VideoFrame> input_frame =
+      CreateRandomMM21Frame(kTestImageSize, VideoFrame::STORAGE_DMABUFS);
+  ASSERT_TRUE(input_frame) << "Error creating input frame";
+  scoped_refptr<VideoFrame> gl_output_frame =
+      CreateNV12Frame(kTestImageSize, VideoFrame::STORAGE_GPU_MEMORY_BUFFER);
+  ASSERT_TRUE(gl_output_frame) << "Error creating GL output frame";
+  scoped_refptr<VideoFrame> libyuv_output_frame =
+      CreateNV12Frame(kTestImageSize, VideoFrame::STORAGE_GPU_MEMORY_BUFFER);
+  ASSERT_TRUE(libyuv_output_frame) << "Error creating LibYUV output frame";
+
+  int outstanding_processors = 2;
+  ImageProcessor::FrameReadyCB libyuv_callback = base::BindOnce(
+      [](scoped_refptr<base::SequencedTaskRunner> client_task_runner,
+         base::RepeatingClosure quit_closure, int* outstanding_processors,
+         scoped_refptr<VideoFrame>* libyuv_output_frame,
+         scoped_refptr<VideoFrame> frame) {
+        CHECK(client_task_runner->RunsTasksInCurrentSequence());
+        *libyuv_output_frame = std::move(frame);
+        if (!(--*outstanding_processors)) {
+          quit_closure.Run();
+        }
+      },
+      client_task_runner, quit_closure, &outstanding_processors,
+      &libyuv_output_frame);
+
+  ImageProcessor::FrameReadyCB gl_callback = base::BindOnce(
+      [](scoped_refptr<base::SequencedTaskRunner> client_task_runner,
+         base::RepeatingClosure quit_closure, int* outstanding_processors,
+         scoped_refptr<VideoFrame>* gl_output_frame,
+         scoped_refptr<VideoFrame> frame) {
+        CHECK(client_task_runner->RunsTasksInCurrentSequence());
+        *gl_output_frame = std::move(frame);
+        if (!(--*outstanding_processors)) {
+          quit_closure.Run();
+        }
+      },
+      client_task_runner, quit_closure, &outstanding_processors,
+      &gl_output_frame);
+
+  libyuv_image_processor->Process(input_frame, libyuv_output_frame,
+                                  std::move(libyuv_callback));
+  gl_image_processor->Process(input_frame, gl_output_frame,
+                              std::move(gl_callback));
+
+  run_loop.Run();
+
+  ASSERT_FALSE(image_processor_error);
+  ASSERT_TRUE(libyuv_output_frame);
+  ASSERT_TRUE(gl_output_frame);
+  ASSERT_TRUE(CompareNV12VideoFrames(gl_output_frame, libyuv_output_frame));
+}
+#endif
+
 }  // namespace
 }  // namespace media
 
diff --git a/media/gpu/mac/vt_config_util_unittest.cc b/media/gpu/mac/vt_config_util_unittest.cc
index f499907..50aa044d 100644
--- a/media/gpu/mac/vt_config_util_unittest.cc
+++ b/media/gpu/mac/vt_config_util_unittest.cc
@@ -9,7 +9,6 @@
 #include "base/containers/span.h"
 #include "base/mac/foundation_util.h"
 #include "base/mac/mac_util.h"
-#include "base/mac/sdk_forward_declarations.h"
 #include "base/strings/sys_string_conversions.h"
 #include "media/base/mac/color_space_util_mac.h"
 #include "media/formats/mp4/box_definitions.h"
diff --git a/media/gpu/mac/vt_video_decode_accelerator_mac.cc b/media/gpu/mac/vt_video_decode_accelerator_mac.cc
index 62ac487..05ec0ba 100644
--- a/media/gpu/mac/vt_video_decode_accelerator_mac.cc
+++ b/media/gpu/mac/vt_video_decode_accelerator_mac.cc
@@ -21,7 +21,6 @@
 #include "base/logging.h"
 #include "base/mac/mac_logging.h"
 #include "base/mac/mac_util.h"
-#include "base/mac/sdk_forward_declarations.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/scoped_policy.h"
 #include "base/metrics/histogram_macros.h"
diff --git a/mojo/public/tools/bindings/mojom.gni b/mojo/public/tools/bindings/mojom.gni
index c0efdd7..1e8ebc6 100644
--- a/mojo/public/tools/bindings/mojom.gni
+++ b/mojo/public/tools/bindings/mojom.gni
@@ -2003,26 +2003,6 @@
         # TODO(crbug.com/1007591): Support generate_fuzzing.
       }
     }
-
-    ts_target_name = target_name + "_ts"
-    group(ts_target_name) {
-      public_deps = []
-      if (sources_list != []) {
-        public_deps += [ ":$generator_ts_target_name" ]
-      }
-
-      foreach(d, all_deps) {
-        full_name = get_label_info(d, "label_no_toolchain")
-        public_deps += [ "${full_name}_js" ]
-      }
-    }
-
-    # Use |js_target_name| to track dependencies since TS targets may depend on
-    # either TS or JS targets.
-    js_target_name = target_name + "_js"
-    group(js_target_name) {
-      public_deps = [ ":$ts_target_name" ]
-    }
   }
 }
 
diff --git a/net/base/url_search_params.cc b/net/base/url_search_params.cc
index ab58114f..62c5aa4b 100644
--- a/net/base/url_search_params.cc
+++ b/net/base/url_search_params.cc
@@ -14,31 +14,8 @@
 #include "base/strings/utf_string_conversions.h"
 #include "net/base/url_util.h"
 #include "url/gurl.h"
-#include "url/url_canon.h"
-#include "url/url_canon_internal.h"
-#include "url/url_util.h"
 
 namespace net {
-namespace {
-
-// The notion of unescaping used in the application/x-www-form-urlencoded
-// parser. https://url.spec.whatwg.org/#concept-urlencoded-parser
-std::string UnescapePercentEncodedUrl(base::StringPiece input) {
-  std::string result(input);
-  // Replace any 0x2B (+) with 0x20 (SP).
-  for (char& c : result) {
-    if (c == '+')
-      c = ' ';
-  }
-  // Run UTF-8 decoding without BOM on the percent-decoding.
-  url::RawCanonOutputT<char16_t> canon_output;
-  url::DecodeURLEscapeSequences(result.data(), result.size(),
-                                url::DecodeURLMode::kUTF8, &canon_output);
-  return base::UTF16ToUTF8(
-      base::StringPiece16(canon_output.data(), canon_output.length()));
-}
-
-}  // namespace
 
 UrlSearchParams::UrlSearchParams(const GURL& url) {
   for (auto it = QueryIterator(url); !it.IsAtEnd(); it.Advance()) {
diff --git a/net/base/url_util.cc b/net/base/url_util.cc
index ed60757..3a51928 100644
--- a/net/base/url_util.cc
+++ b/net/base/url_util.cc
@@ -26,6 +26,7 @@
 #include "url/gurl.h"
 #include "url/scheme_host_port.h"
 #include "url/url_canon.h"
+#include "url/url_canon_internal.h"
 #include "url/url_canon_ip.h"
 #include "url/url_constants.h"
 #include "url/url_util.h"
@@ -523,4 +524,20 @@
          IsNormalizedLocalhostTLD(host);
 }
 
+std::string UnescapePercentEncodedUrl(base::StringPiece input) {
+  std::string result(input);
+  // Replace any 0x2B (+) with 0x20 (SP).
+  for (char& c : result) {
+    if (c == '+') {
+      c = ' ';
+    }
+  }
+  // Run UTF-8 decoding without BOM on the percent-decoding.
+  url::RawCanonOutputT<char16_t> canon_output;
+  url::DecodeURLEscapeSequences(result.data(), result.size(),
+                                url::DecodeURLMode::kUTF8, &canon_output);
+  return base::UTF16ToUTF8(
+      base::StringPiece16(canon_output.data(), canon_output.length()));
+}
+
 }  // namespace net
diff --git a/net/base/url_util.h b/net/base/url_util.h
index 9ace034..3038f208 100644
--- a/net/base/url_util.h
+++ b/net/base/url_util.h
@@ -245,6 +245,11 @@
 // |host| is normalized before being tested.
 NET_EXPORT_PRIVATE bool IsLocalHostname(base::StringPiece host);
 
+// The notion of unescaping used in the application/x-www-form-urlencoded
+// parser. https://url.spec.whatwg.org/#concept-urlencoded-parser
+NET_EXPORT_PRIVATE std::string UnescapePercentEncodedUrl(
+    base::StringPiece input);
+
 }  // namespace net
 
 #endif  // NET_BASE_URL_UTIL_H_
diff --git a/net/cert/cert_verify_proc_blocklist.inc b/net/cert/cert_verify_proc_blocklist.inc
index f543de9f..29561f7c 100644
--- a/net/cert/cert_verify_proc_blocklist.inc
+++ b/net/cert/cert_verify_proc_blocklist.inc
@@ -141,6 +141,10 @@
         {0x7a, 0xed, 0xdd, 0xf3, 0x6b, 0x18, 0xf8, 0xac, 0xb7, 0x37, 0x9f,
          0xe1, 0xce, 0x18, 0x32, 0x12, 0xb2, 0x35, 0x0d, 0x07, 0x88, 0xab,
          0xe0, 0xe8, 0x24, 0x57, 0xbe, 0x9b, 0xad, 0xad, 0x6d, 0x54},
+        // 5a885db19c01d912c5759388938cafbbdf031ab2d48e91ee15589b42971d039c.pem
+        {0x7a, 0xfe, 0x4b, 0x07, 0x1a, 0x2f, 0x1f, 0x46, 0xf8, 0xba, 0x94,
+         0x4a, 0x26, 0xd5, 0x84, 0xd5, 0x96, 0x0b, 0x92, 0xfb, 0x48, 0xc3,
+         0xba, 0x1b, 0x7c, 0xab, 0x84, 0x90, 0x5f, 0x32, 0xaa, 0xcd},
         // c43807a64c51a3fbde5421011698013d8b46f4e315c46186dc23aea2670cd34f.pem
         {0x7c, 0xd2, 0x95, 0xb7, 0x55, 0x44, 0x80, 0x8a, 0xbd, 0x94, 0x09,
          0x46, 0x6f, 0x08, 0x37, 0xc5, 0xaa, 0xdc, 0x02, 0xe3, 0x3b, 0x61,
@@ -260,6 +264,10 @@
         {0xc6, 0x01, 0x23, 0x4e, 0x2b, 0x93, 0x25, 0xdc, 0x92, 0xe3, 0xea,
          0xba, 0xc1, 0x96, 0x00, 0xb0, 0xb4, 0x99, 0x47, 0xd4, 0xd0, 0x4d,
          0x8c, 0x99, 0xd3, 0x21, 0x27, 0x49, 0x3e, 0xa0, 0x28, 0xf8},
+        // 0753e940378c1bd5e3836e395daea5cb839e5046f1bd0eae1951cf10fec7c965.pem
+        {0xc6, 0x3d, 0x68, 0xc6, 0x48, 0xa1, 0x8b, 0x77, 0x64, 0x1c, 0x42,
+         0x7a, 0x66, 0x9d, 0x61, 0xc9, 0x76, 0x8a, 0x55, 0xf4, 0xfc, 0xd0,
+         0x32, 0x2e, 0xac, 0x96, 0xc5, 0x77, 0x00, 0x29, 0x9c, 0xf1},
         // 53d48e7b8869a3314f213fd2e0178219ca09022dbe50053bf6f76fccd61e8112.pem
         {0xc8, 0xfd, 0xdc, 0x75, 0xcb, 0x1b, 0xdb, 0xb5, 0x8c, 0x07, 0xb4,
          0xea, 0x84, 0x72, 0x87, 0xf6, 0x26, 0x65, 0x9d, 0xd6, 0x6b, 0xc1,
@@ -323,6 +331,10 @@
         {0xea, 0x08, 0xc8, 0xd4, 0x5d, 0x52, 0xca, 0x59, 0x3d, 0xe5, 0x24,
          0xf0, 0x51, 0x3c, 0xa6, 0x41, 0x8d, 0xa9, 0x85, 0x9f, 0x7b, 0x08,
          0xef, 0x13, 0xff, 0x9d, 0xd7, 0xbf, 0x61, 0x2d, 0x6a, 0x37},
+        // d40e9c86cd8fe468c1776959f49ea774fa548684b6c406f3909261f4dce2575c.pem
+        {0xea, 0x87, 0xf4, 0x62, 0xde, 0xef, 0xff, 0xbd, 0x77, 0x75, 0xaa,
+         0x2a, 0x4b, 0x7e, 0x0f, 0xcb, 0x91, 0xc2, 0x2e, 0xee, 0x6d, 0xf6,
+         0x9e, 0xd9, 0x01, 0x00, 0xcc, 0xc7, 0x3b, 0x31, 0x14, 0x76},
         // 60911c79835c3739432d08c45df64311e06985c5889dc5420ce3d142c8c7ef58.pem
         {0xef, 0x55, 0x12, 0x84, 0x71, 0x52, 0x32, 0xde, 0x92, 0xe2, 0x46,
          0xc3, 0x23, 0x32, 0x93, 0x62, 0xb1, 0x32, 0x49, 0x3b, 0xb1, 0x6b,
diff --git a/net/cert/internal/system_trust_store.cc b/net/cert/internal/system_trust_store.cc
index b7d4506..9706f806 100644
--- a/net/cert/internal/system_trust_store.cc
+++ b/net/cert/internal/system_trust_store.cc
@@ -377,6 +377,10 @@
   static base::NoDestructor<TrustStoreWin> static_trust_store_win;
   return static_trust_store_win.get();
 }
+
+void InitializeTrustStoreForCRSOnWorkerThread() {
+  GetGlobalTrustStoreWinForCRS()->InitializeStores();
+}
 }  // namespace
 
 std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStoreChromeRoot(
@@ -385,6 +389,19 @@
       std::move(chrome_root), GetGlobalTrustStoreWinForCRS());
 }
 
+// We do this in a separate thread as loading the Windows Cert Stores can cause
+// quite a bit of I/O. See crbug.com/1399974 for more context.
+void InitializeTrustStoreWinSystem() {
+  base::ThreadPool::PostTask(
+      FROM_HERE,
+      {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
+      base::BindOnce(&InitializeTrustStoreForCRSOnWorkerThread));
+}
+
+#else
+
+void InitializeTrustStoreWinSystem() {}
+
 #endif  // CHROME_ROOT_STORE_SUPPORTED
 
 #elif BUILDFLAG(IS_ANDROID)
diff --git a/net/cert/internal/system_trust_store.h b/net/cert/internal/system_trust_store.h
index 758891f..22b0af0 100644
--- a/net/cert/internal/system_trust_store.h
+++ b/net/cert/internal/system_trust_store.h
@@ -103,6 +103,12 @@
 NET_EXPORT void InitializeTrustStoreMacCache();
 #endif
 
+#if BUILDFLAG(IS_WIN)
+// Initializes windows system trust store on a worker thread, if the builtin
+// verifier is enabled.
+NET_EXPORT void InitializeTrustStoreWinSystem();
+#endif
+
 }  // namespace net
 
 #endif  // NET_CERT_INTERNAL_SYSTEM_TRUST_STORE_H_
diff --git a/net/cert/internal/trust_store_win.cc b/net/cert/internal/trust_store_win.cc
index 8246ac4..7e472de 100644
--- a/net/cert/internal/trust_store_win.cc
+++ b/net/cert/internal/trust_store_win.cc
@@ -5,10 +5,12 @@
 #include "net/cert/internal/trust_store_win.h"
 
 #include "base/hash/sha1.h"
+#include "base/location.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/ranges/algorithm.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/threading/scoped_blocking_call.h"
 #include "net/cert/pki/cert_errors.h"
 #include "net/cert/pki/parsed_certificate.h"
 #include "net/cert/x509_util.h"
@@ -79,98 +81,235 @@
 
 }  // namespace
 
+class TrustStoreWin::Impl {
+ public:
+  // Creates a TrustStoreWin.
+  Impl() {
+    base::ScopedBlockingCall scoped_blocking_call(
+        FROM_HERE, base::BlockingType::MAY_BLOCK);
+
+    crypto::ScopedHCERTSTORE root_cert_store(
+        CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, NULL, 0, nullptr));
+    crypto::ScopedHCERTSTORE intermediate_cert_store(
+        CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, NULL, 0, nullptr));
+    crypto::ScopedHCERTSTORE all_certs_store(
+        CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, NULL, 0, nullptr));
+    crypto::ScopedHCERTSTORE disallowed_cert_store(
+        CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, NULL, 0, nullptr));
+    if (!root_cert_store.get() || !intermediate_cert_store.get() ||
+        !all_certs_store.get() || !disallowed_cert_store.get()) {
+      return;
+    }
+
+    // Add intermediate and root cert stores to the all_cert_store collection so
+    // SyncGetIssuersOf will find them. disallowed_cert_store is not added
+    // because the certs are distrusted; making them non-findable in
+    // SyncGetIssuersOf helps us fail path-building faster.
+    if (!CertAddStoreToCollection(all_certs_store.get(),
+                                  intermediate_cert_store.get(),
+                                  /*dwUpdateFlags=*/0, /*dwPriority=*/0)) {
+      return;
+    }
+    if (!CertAddStoreToCollection(all_certs_store.get(), root_cert_store.get(),
+                                  /*dwUpdateFlags=*/0, /*dwPriority=*/0)) {
+      return;
+    }
+
+    // Grab the user-added roots.
+    GatherEnterpriseCertsForLocation(root_cert_store.get(),
+                                     CERT_SYSTEM_STORE_LOCAL_MACHINE, L"ROOT");
+    GatherEnterpriseCertsForLocation(
+        root_cert_store.get(), CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY,
+        L"ROOT");
+    GatherEnterpriseCertsForLocation(root_cert_store.get(),
+                                     CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE,
+                                     L"ROOT");
+    GatherEnterpriseCertsForLocation(root_cert_store.get(),
+                                     CERT_SYSTEM_STORE_CURRENT_USER, L"ROOT");
+    GatherEnterpriseCertsForLocation(
+        root_cert_store.get(), CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY,
+        L"ROOT");
+
+    // Grab the user-added intermediates.
+    GatherEnterpriseCertsForLocation(intermediate_cert_store.get(),
+                                     CERT_SYSTEM_STORE_LOCAL_MACHINE, L"CA");
+    GatherEnterpriseCertsForLocation(
+        intermediate_cert_store.get(),
+        CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY, L"CA");
+    GatherEnterpriseCertsForLocation(intermediate_cert_store.get(),
+                                     CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE,
+                                     L"CA");
+    GatherEnterpriseCertsForLocation(intermediate_cert_store.get(),
+                                     CERT_SYSTEM_STORE_CURRENT_USER, L"CA");
+    GatherEnterpriseCertsForLocation(
+        intermediate_cert_store.get(),
+        CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY, L"CA");
+
+    // Grab the user-added disallowed certs.
+    GatherEnterpriseCertsForLocation(disallowed_cert_store.get(),
+                                     CERT_SYSTEM_STORE_LOCAL_MACHINE,
+                                     L"Disallowed");
+    GatherEnterpriseCertsForLocation(
+        disallowed_cert_store.get(),
+        CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY, L"Disallowed");
+    GatherEnterpriseCertsForLocation(disallowed_cert_store.get(),
+                                     CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE,
+                                     L"Disallowed");
+    GatherEnterpriseCertsForLocation(disallowed_cert_store.get(),
+                                     CERT_SYSTEM_STORE_CURRENT_USER,
+                                     L"Disallowed");
+    GatherEnterpriseCertsForLocation(
+        disallowed_cert_store.get(),
+        CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY, L"Disallowed");
+
+    // Auto-sync all of the cert stores to get updates to the cert store.
+    // Auto-syncing on all_certs_store seems to work to resync the nested
+    // stores, although the docs at
+    // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certcontrolstore
+    // are somewhat unclear. If and when root store changes are linked to
+    // clearing various caches, this should be replaced with
+    // CERT_STORE_CTRL_NOTIFY_CHANGE and CERT_STORE_CTRL_RESYNC.
+    if (!CertControlStore(all_certs_store.get(), 0, CERT_STORE_CTRL_AUTO_RESYNC,
+                          0)) {
+      PLOG(ERROR) << "Error enabling CERT_STORE_CTRL_AUTO_RESYNC";
+    }
+
+    root_cert_store_ = std::move(root_cert_store);
+    intermediate_cert_store_ = std::move(intermediate_cert_store);
+    disallowed_cert_store_ = std::move(disallowed_cert_store);
+    all_certs_store_ = std::move(all_certs_store);
+  }
+
+  // all_certs_store should be a combination of root_cert_store and
+  // intermediate_cert_store, but we ask callers to explicitly pass this in so
+  // that all the error checking can happen outside of the constructor.
+  Impl(crypto::ScopedHCERTSTORE root_cert_store,
+       crypto::ScopedHCERTSTORE intermediate_cert_store,
+       crypto::ScopedHCERTSTORE disallowed_cert_store,
+       crypto::ScopedHCERTSTORE all_certs_store)
+      : root_cert_store_(std::move(root_cert_store)),
+        intermediate_cert_store_(std::move(intermediate_cert_store)),
+        all_certs_store_(std::move(all_certs_store)),
+        disallowed_cert_store_(std::move(disallowed_cert_store)) {}
+
+  ~Impl() = default;
+  Impl(const Impl& other) = delete;
+  Impl& operator=(const Impl& other) = delete;
+
+  void SyncGetIssuersOf(const ParsedCertificate* cert,
+                        ParsedCertificateList* issuers) {
+    if (!root_cert_store_.get() || !intermediate_cert_store_.get() ||
+        !all_certs_store_.get() || !disallowed_cert_store_.get()) {
+      return;
+    }
+    base::span<const uint8_t> issuer_span = cert->issuer_tlv().AsSpan();
+
+    CERT_NAME_BLOB cert_issuer_blob;
+    cert_issuer_blob.cbData = static_cast<DWORD>(issuer_span.size());
+    cert_issuer_blob.pbData = const_cast<uint8_t*>(issuer_span.data());
+
+    PCCERT_CONTEXT cert_from_store = nullptr;
+    // TODO(https://crbug.com/1239270): figure out if this is thread-safe or if
+    // we need locking here
+    while ((cert_from_store = CertFindCertificateInStore(
+                all_certs_store_.get(), X509_ASN_ENCODING, 0,
+                CERT_FIND_SUBJECT_NAME, &cert_issuer_blob, cert_from_store))) {
+      bssl::UniquePtr<CRYPTO_BUFFER> der_crypto =
+          x509_util::CreateCryptoBuffer(base::make_span(
+              cert_from_store->pbCertEncoded, cert_from_store->cbCertEncoded));
+      CertErrors errors;
+      ParsedCertificate::CreateAndAddToVector(
+          std::move(der_crypto), x509_util::DefaultParseCertificateOptions(),
+          issuers, &errors);
+    }
+  }
+
+  CertificateTrust GetTrust(const ParsedCertificate* cert,
+                            base::SupportsUserData* debug_data) {
+    if (!root_cert_store_.get() || !intermediate_cert_store_.get() ||
+        !all_certs_store_.get() || !disallowed_cert_store_.get()) {
+      return CertificateTrust::ForUnspecified();
+    }
+
+    base::span<const uint8_t> cert_span = cert->der_cert().AsSpan();
+    base::SHA1Digest cert_hash = base::SHA1HashSpan(cert_span);
+    CRYPT_HASH_BLOB cert_hash_blob;
+    cert_hash_blob.cbData = static_cast<DWORD>(cert_hash.size());
+    cert_hash_blob.pbData = cert_hash.data();
+
+    PCCERT_CONTEXT cert_from_store = nullptr;
+
+    // Check Disallowed store first.
+    while ((cert_from_store = CertFindCertificateInStore(
+                disallowed_cert_store_.get(), X509_ASN_ENCODING, 0,
+                CERT_FIND_SHA1_HASH, &cert_hash_blob, cert_from_store))) {
+      base::span<const uint8_t> cert_from_store_span = base::make_span(
+          cert_from_store->pbCertEncoded, cert_from_store->cbCertEncoded);
+      // If a cert is in the windows distruted store, it is considered
+      // distrusted for all purporses. EKU isn't checked. See crbug.com/1355961.
+      if (base::ranges::equal(cert_span, cert_from_store_span)) {
+        return CertificateTrust::ForDistrusted();
+      }
+    }
+
+    // TODO(https://crbug.com/1239270): figure out if this is thread-safe or if
+    // we need locking here
+    while ((cert_from_store = CertFindCertificateInStore(
+                root_cert_store_.get(), X509_ASN_ENCODING, 0,
+                CERT_FIND_SHA1_HASH, &cert_hash_blob, cert_from_store))) {
+      base::span<const uint8_t> cert_from_store_span = base::make_span(
+          cert_from_store->pbCertEncoded, cert_from_store->cbCertEncoded);
+      if (base::ranges::equal(cert_span, cert_from_store_span)) {
+        // If we find at least one version of the cert that is trusted for TLS
+        // Server Auth, we will trust the cert.
+        if (IsCertTrustedForServerAuth(cert_from_store)) {
+          return CertificateTrust::ForTrustAnchor().WithEnforceAnchorExpiry();
+        }
+      }
+    }
+
+    // If we fall through here, we've either
+    //
+    // (a) found the cert but it is not usable for server auth. Treat this as
+    //     Unspecified trust. Originally this was treated as Distrusted, but
+    //     this is inconsistent with how the Windows verifier works, which is to
+    //     union all of the EKU usages for all instances of the cert, whereas
+    //     sending back Distrusted would not do that.
+    //
+    // or
+    //
+    // (b) Haven't found the cert. Tell everyone Unspecified.
+    return CertificateTrust::ForUnspecified();
+  }
+
+ private:
+  // Cert Collection containing all user-added trust anchors.
+  crypto::ScopedHCERTSTORE root_cert_store_;
+
+  // Cert Collection containing all user-added intermediates.
+  crypto::ScopedHCERTSTORE intermediate_cert_store_;
+
+  // Cert Collection for searching via SyncGetIssuersOf()
+  crypto::ScopedHCERTSTORE all_certs_store_;
+
+  // Cert Collection for all disallowed certs.
+  crypto::ScopedHCERTSTORE disallowed_cert_store_;
+};
+
 // TODO(https://crbug.com/1239268): support CTLs.
-TrustStoreWin::TrustStoreWin() {
-  crypto::ScopedHCERTSTORE root_cert_store(
-      CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, NULL, 0, nullptr));
-  crypto::ScopedHCERTSTORE intermediate_cert_store(
-      CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, NULL, 0, nullptr));
-  crypto::ScopedHCERTSTORE all_certs_store(
-      CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, NULL, 0, nullptr));
-  crypto::ScopedHCERTSTORE disallowed_cert_store(
-      CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, NULL, 0, nullptr));
-  if (!root_cert_store.get() || !intermediate_cert_store.get() ||
-      !all_certs_store.get() || !disallowed_cert_store.get()) {
-    return;
+TrustStoreWin::TrustStoreWin() = default;
+
+void TrustStoreWin::InitializeStores() {
+  // Don't need return value
+  MaybeInitializeAndGetImpl();
+}
+
+TrustStoreWin::Impl* TrustStoreWin::MaybeInitializeAndGetImpl() {
+  base::AutoLock lock(init_lock_);
+  if (!impl_) {
+    impl_ = std::make_unique<TrustStoreWin::Impl>();
   }
-
-  // Add intermediate and root cert stores to the all_cert_store collection so
-  // SyncGetIssuersOf will find them. disallowed_cert_store is not added
-  // because the certs are distrusted; making them non-findable in
-  // SyncGetIssuersOf helps us fail path-building faster.
-  if (!CertAddStoreToCollection(all_certs_store.get(),
-                                intermediate_cert_store.get(),
-                                /*dwUpdateFlags=*/0, /*dwPriority=*/0)) {
-    return;
-  }
-  if (!CertAddStoreToCollection(all_certs_store.get(), root_cert_store.get(),
-                                /*dwUpdateFlags=*/0, /*dwPriority=*/0)) {
-    return;
-  }
-
-  // Grab the user-added roots.
-  GatherEnterpriseCertsForLocation(root_cert_store.get(),
-                                   CERT_SYSTEM_STORE_LOCAL_MACHINE, L"ROOT");
-  GatherEnterpriseCertsForLocation(root_cert_store.get(),
-                                   CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY,
-                                   L"ROOT");
-  GatherEnterpriseCertsForLocation(root_cert_store.get(),
-                                   CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE,
-                                   L"ROOT");
-  GatherEnterpriseCertsForLocation(root_cert_store.get(),
-                                   CERT_SYSTEM_STORE_CURRENT_USER, L"ROOT");
-  GatherEnterpriseCertsForLocation(root_cert_store.get(),
-                                   CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY,
-                                   L"ROOT");
-
-  // Grab the user-added intermediates.
-  GatherEnterpriseCertsForLocation(intermediate_cert_store.get(),
-                                   CERT_SYSTEM_STORE_LOCAL_MACHINE, L"CA");
-  GatherEnterpriseCertsForLocation(intermediate_cert_store.get(),
-                                   CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY,
-                                   L"CA");
-  GatherEnterpriseCertsForLocation(intermediate_cert_store.get(),
-                                   CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE,
-                                   L"CA");
-  GatherEnterpriseCertsForLocation(intermediate_cert_store.get(),
-                                   CERT_SYSTEM_STORE_CURRENT_USER, L"CA");
-  GatherEnterpriseCertsForLocation(intermediate_cert_store.get(),
-                                   CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY,
-                                   L"CA");
-
-  // Grab the user-added disallowed certs.
-  GatherEnterpriseCertsForLocation(disallowed_cert_store.get(),
-                                   CERT_SYSTEM_STORE_LOCAL_MACHINE,
-                                   L"Disallowed");
-  GatherEnterpriseCertsForLocation(disallowed_cert_store.get(),
-                                   CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY,
-                                   L"Disallowed");
-  GatherEnterpriseCertsForLocation(disallowed_cert_store.get(),
-                                   CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE,
-                                   L"Disallowed");
-  GatherEnterpriseCertsForLocation(disallowed_cert_store.get(),
-                                   CERT_SYSTEM_STORE_CURRENT_USER,
-                                   L"Disallowed");
-  GatherEnterpriseCertsForLocation(disallowed_cert_store.get(),
-                                   CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY,
-                                   L"Disallowed");
-
-  // Auto-sync all of the cert stores to get updates to the cert store.
-  // Auto-syncing on all_certs_store seems to work to resync the nested stores,
-  // although the docs at
-  // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certcontrolstore
-  // are somewhat unclear. If and when root store changes are linked to clearing
-  // various caches, this should be replaced with CERT_STORE_CTRL_NOTIFY_CHANGE
-  // and CERT_STORE_CTRL_RESYNC.
-  if (!CertControlStore(all_certs_store.get(), 0, CERT_STORE_CTRL_AUTO_RESYNC,
-                        0)) {
-    PLOG(ERROR) << "Error enabling CERT_STORE_CTRL_AUTO_RESYNC";
-  }
-
-  root_cert_store_ = std::move(root_cert_store);
-  intermediate_cert_store_ = std::move(intermediate_cert_store);
-  disallowed_cert_store_ = std::move(disallowed_cert_store);
-  all_certs_store_ = std::move(all_certs_store);
+  return impl_.get();
 }
 
 std::unique_ptr<TrustStoreWin> TrustStoreWin::CreateForTesting(
@@ -190,51 +329,20 @@
                              /*dwUpdateFlags=*/0, /*dwPriority=*/0);
   }
 
-  return base::WrapUnique(new TrustStoreWin(
-      std::move(root_cert_store), std::move(intermediate_cert_store),
-      std::move(disallowed_cert_store), std::move(all_certs_store)));
+  return base::WrapUnique(
+      new TrustStoreWin(std::make_unique<TrustStoreWin::Impl>(
+          std::move(root_cert_store), std::move(intermediate_cert_store),
+          std::move(disallowed_cert_store), std::move(all_certs_store))));
 }
 
-// all_certs_store should be a combination of root_cert_store and
-// intermediate_cert_store, but we ask callers to explicitly pass this in so
-// that all the error checking can happen outside of the constructor.
-TrustStoreWin::TrustStoreWin(crypto::ScopedHCERTSTORE root_cert_store,
-                             crypto::ScopedHCERTSTORE intermediate_cert_store,
-                             crypto::ScopedHCERTSTORE disallowed_cert_store,
-                             crypto::ScopedHCERTSTORE all_certs_store)
-    : root_cert_store_(std::move(root_cert_store)),
-      intermediate_cert_store_(std::move(intermediate_cert_store)),
-      all_certs_store_(std::move(all_certs_store)),
-      disallowed_cert_store_(std::move(disallowed_cert_store)) {}
+TrustStoreWin::TrustStoreWin(std::unique_ptr<Impl> impl)
+    : impl_(std::move(impl)) {}
 
 TrustStoreWin::~TrustStoreWin() = default;
 
 void TrustStoreWin::SyncGetIssuersOf(const ParsedCertificate* cert,
                                      ParsedCertificateList* issuers) {
-  if (!root_cert_store_.get() || !intermediate_cert_store_.get() ||
-      !all_certs_store_.get() || !disallowed_cert_store_.get()) {
-    return;
-  }
-  base::span<const uint8_t> issuer_span = cert->issuer_tlv().AsSpan();
-
-  CERT_NAME_BLOB cert_issuer_blob;
-  cert_issuer_blob.cbData = static_cast<DWORD>(issuer_span.size());
-  cert_issuer_blob.pbData = const_cast<uint8_t*>(issuer_span.data());
-
-  PCCERT_CONTEXT cert_from_store = nullptr;
-  // TODO(https://crbug.com/1239270): figure out if this is thread-safe or if we
-  // need locking here
-  while ((cert_from_store = CertFindCertificateInStore(
-              all_certs_store_.get(), X509_ASN_ENCODING, 0,
-              CERT_FIND_SUBJECT_NAME, &cert_issuer_blob, cert_from_store))) {
-    bssl::UniquePtr<CRYPTO_BUFFER> der_crypto =
-        x509_util::CreateCryptoBuffer(base::make_span(
-            cert_from_store->pbCertEncoded, cert_from_store->cbCertEncoded));
-    CertErrors errors;
-    ParsedCertificate::CreateAndAddToVector(
-        std::move(der_crypto), x509_util::DefaultParseCertificateOptions(),
-        issuers, &errors);
-  }
+  MaybeInitializeAndGetImpl()->SyncGetIssuersOf(cert, issuers);
 }
 
 // As documented in IsCertTrustedForServerAuth(), on Windows, the
@@ -269,60 +377,7 @@
 // is usable for TLS server auth.
 CertificateTrust TrustStoreWin::GetTrust(const ParsedCertificate* cert,
                                          base::SupportsUserData* debug_data) {
-  if (!root_cert_store_.get() || !intermediate_cert_store_.get() ||
-      !all_certs_store_.get() || !disallowed_cert_store_.get()) {
-    return CertificateTrust::ForUnspecified();
-  }
-
-  base::span<const uint8_t> cert_span = cert->der_cert().AsSpan();
-  base::SHA1Digest cert_hash = base::SHA1HashSpan(cert_span);
-  CRYPT_HASH_BLOB cert_hash_blob;
-  cert_hash_blob.cbData = static_cast<DWORD>(cert_hash.size());
-  cert_hash_blob.pbData = cert_hash.data();
-
-  PCCERT_CONTEXT cert_from_store = nullptr;
-
-  // Check Disallowed store first.
-  while ((cert_from_store = CertFindCertificateInStore(
-              disallowed_cert_store_.get(), X509_ASN_ENCODING, 0,
-              CERT_FIND_SHA1_HASH, &cert_hash_blob, cert_from_store))) {
-    base::span<const uint8_t> cert_from_store_span = base::make_span(
-        cert_from_store->pbCertEncoded, cert_from_store->cbCertEncoded);
-    // If a cert is in the windows distruted store, it is considered
-    // distrusted for all purporses. EKU isn't checked. See crbug.com/1355961.
-    if (base::ranges::equal(cert_span, cert_from_store_span)) {
-      return CertificateTrust::ForDistrusted();
-    }
-  }
-
-  // TODO(https://crbug.com/1239270): figure out if this is thread-safe or if we
-  // need locking here
-  while ((cert_from_store = CertFindCertificateInStore(
-              root_cert_store_.get(), X509_ASN_ENCODING, 0, CERT_FIND_SHA1_HASH,
-              &cert_hash_blob, cert_from_store))) {
-    base::span<const uint8_t> cert_from_store_span = base::make_span(
-        cert_from_store->pbCertEncoded, cert_from_store->cbCertEncoded);
-    if (base::ranges::equal(cert_span, cert_from_store_span)) {
-      // If we find at least one version of the cert that is trusted for TLS
-      // Server Auth, we will trust the cert.
-      if (IsCertTrustedForServerAuth(cert_from_store)) {
-        return CertificateTrust::ForTrustAnchor().WithEnforceAnchorExpiry();
-      }
-    }
-  }
-
-  // If we fall through here, we've either
-  //
-  // (a) found the cert but it is not usable for server auth. Treat this as
-  //     Unspecified trust. Originally this was treated as Distrusted, but this
-  //     is inconsistent with how the Windows verifier works, which is to union
-  //     all of the EKU usages for all instances of the cert, whereas sending
-  //     back Distrusted would not do that.
-  //
-  // or
-  //
-  // (b) Haven't found the cert. Tell everyone Unspecified.
-  return CertificateTrust::ForUnspecified();
+  return MaybeInitializeAndGetImpl()->GetTrust(cert, debug_data);
 }
 
 }  // namespace net
diff --git a/net/cert/internal/trust_store_win.h b/net/cert/internal/trust_store_win.h
index 908948e..5f86ccb4 100644
--- a/net/cert/internal/trust_store_win.h
+++ b/net/cert/internal/trust_store_win.h
@@ -6,6 +6,7 @@
 #define NET_CERT_INTERNAL_TRUST_STORE_WIN_H_
 
 #include "base/memory/ptr_util.h"
+#include "base/synchronization/lock.h"
 #include "base/win/wincrypt_shim.h"
 #include "crypto/scoped_capi_types.h"
 #include "net/base/net_export.h"
@@ -19,9 +20,7 @@
 // TODO(https://crbug.com/1239270): confirm this is thread safe.
 class NET_EXPORT TrustStoreWin : public TrustStore {
  public:
-  // Creates a TrustStoreWin by reading user settings from Windows system
-  // CertStores. If there are errors, will return a TrustStoreWin object
-  // that may not read all Windows system CertStores.
+  // Creates a TrustStoreWin.
   TrustStoreWin();
 
   ~TrustStoreWin() override;
@@ -37,6 +36,11 @@
       crypto::ScopedHCERTSTORE intermediate_cert_store,
       crypto::ScopedHCERTSTORE disallowed_cert_store);
 
+  // Loads user settings from Windows CertStores. If there are errors,
+  // the underlyingTrustStoreWin object may not read all Windows
+  // CertStores when making trust decisions.
+  void InitializeStores();
+
   void SyncGetIssuersOf(const ParsedCertificate* cert,
                         ParsedCertificateList* issuers) override;
 
@@ -44,22 +48,17 @@
                             base::SupportsUserData* debug_data) override;
 
  private:
-  TrustStoreWin(crypto::ScopedHCERTSTORE root_cert_store,
-                crypto::ScopedHCERTSTORE intermediate_cert_store,
-                crypto::ScopedHCERTSTORE disallowed_cert_store,
-                crypto::ScopedHCERTSTORE all_certs_store);
+  // Inner Impl class for use in initializing stores.
+  class Impl;
 
-  // Cert Collection containing all user-added trust anchors.
-  crypto::ScopedHCERTSTORE root_cert_store_;
+  explicit TrustStoreWin(std::unique_ptr<Impl> impl);
 
-  // Cert Collection containing all user-added intermediates.
-  crypto::ScopedHCERTSTORE intermediate_cert_store_;
+  // Loads user settings from Windows CertStores if not already done and
+  // returns pointer to the Impl.
+  Impl* MaybeInitializeAndGetImpl();
 
-  // Cert Collection for searching via SyncGetIssuersOf()
-  crypto::ScopedHCERTSTORE all_certs_store_;
-
-  // Cert Collection for all disallowed certs.
-  crypto::ScopedHCERTSTORE disallowed_cert_store_;
+  base::Lock init_lock_;
+  std::unique_ptr<Impl> impl_ GUARDED_BY(init_lock_);
 };
 
 }  // namespace net
diff --git a/net/data/ssl/blocklist/0753e940378c1bd5e3836e395daea5cb839e5046f1bd0eae1951cf10fec7c965.pem b/net/data/ssl/blocklist/0753e940378c1bd5e3836e395daea5cb839e5046f1bd0eae1951cf10fec7c965.pem
new file mode 100644
index 0000000..6e8d322
--- /dev/null
+++ b/net/data/ssl/blocklist/0753e940378c1bd5e3836e395daea5cb839e5046f1bd0eae1951cf10fec7c965.pem
@@ -0,0 +1,126 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 2711694510199101698 (0x25a1dfca33cb5902)
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C = PA, ST = Panama, L = Panama City, O = TrustCor Systems S. de R.L., OU = TrustCor Certificate Authority, CN = TrustCor RootCert CA-2
+        Validity
+            Not Before: Feb  4 12:32:23 2016 GMT
+            Not After : Dec 31 17:26:39 2034 GMT
+        Subject: C = PA, ST = Panama, L = Panama City, O = TrustCor Systems S. de R.L., OU = TrustCor Certificate Authority, CN = TrustCor RootCert CA-2
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (4096 bit)
+                Modulus:
+                    00:a7:20:6e:c2:2a:a2:62:24:95:90:76:c8:38:7e:
+                    80:d2:ab:c1:9b:65:05:94:f4:c1:0a:10:d5:02:ac:
+                    ed:9f:93:c7:87:c8:b0:27:2b:42:0c:3d:0a:3e:41:
+                    5a:9e:75:dd:8d:ca:e0:9b:ec:68:32:a4:69:92:68:
+                    8c:0b:81:0e:56:a0:3e:1a:dd:2c:25:14:82:2f:97:
+                    d3:64:46:f4:54:a9:dc:3a:54:2d:31:2b:99:82:f2:
+                    d9:2a:d7:ef:71:00:b8:31:a4:be:7a:24:07:c3:42:
+                    20:f2:8a:d4:92:04:1b:65:56:4c:6c:d4:fb:b6:61:
+                    5a:47:23:b4:d8:69:b4:b7:3a:d0:74:3c:0c:75:a1:
+                    8c:4e:76:a1:e9:db:2a:a5:3b:fa:ce:b0:ff:7e:6a:
+                    28:fd:27:1c:c8:b1:e9:29:f1:57:6e:64:b4:d0:c1:
+                    15:6d:0e:be:2e:0e:46:c8:5e:f4:51:fe:ef:0e:63:
+                    3a:3b:71:ba:cf:6f:59:ca:0c:e3:9b:5d:49:b8:4c:
+                    e2:57:b1:98:8a:42:57:9c:76:ef:ef:bd:d1:68:a8:
+                    d2:f4:09:bb:77:35:be:25:82:08:c4:16:2c:44:20:
+                    56:a9:44:11:77:ef:5d:b4:1d:aa:5e:6b:3e:8b:32:
+                    f6:07:2f:57:04:92:ca:f5:fe:9d:c2:e9:e8:b3:8e:
+                    4c:4b:02:31:d9:e4:3c:48:82:27:f7:18:82:76:48:
+                    3a:71:b1:13:a1:39:d5:2e:c5:34:c2:1d:62:85:df:
+                    03:fe:4d:f4:af:3d:df:5c:5b:8d:fa:70:e1:a5:7e:
+                    27:c7:86:2e:6a:8f:12:c6:84:5e:43:51:50:9c:19:
+                    9b:78:e6:fc:f6:ed:47:7e:7b:3d:66:ef:13:13:88:
+                    5f:3c:a1:63:fb:f9:ac:87:35:9f:f3:82:9e:a4:3f:
+                    0a:9c:31:69:8b:99:a4:88:4a:8e:6e:66:4d:ef:16:
+                    c4:0f:79:28:21:60:0d:85:16:7d:d7:54:38:f1:92:
+                    56:fd:b5:33:4c:83:dc:d7:10:9f:4b:fd:c6:f8:42:
+                    bd:ba:7c:73:02:e0:ff:7d:cd:5b:e1:d4:ac:61:7b:
+                    57:d5:4a:7b:5b:d4:85:58:27:5d:bf:f8:2b:60:ac:
+                    a0:26:ae:14:21:27:c6:77:9a:33:80:3c:5e:46:3f:
+                    f7:c3:b1:a3:86:33:c6:e8:5e:0d:b9:35:2c:aa:46:
+                    c1:85:02:75:80:a0:eb:24:fb:15:aa:e4:67:7f:6e:
+                    77:3f:f4:04:8a:2f:7c:7b:e3:17:61:f0:dd:09:a9:
+                    20:c8:be:09:a4:d0:7e:44:c3:b2:30:4a:38:aa:a9:
+                    ec:18:9a:07:82:2b:db:b8:9c:18:ad:da:e0:46:17:
+                    ac:cf:5d
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Subject Key Identifier: 
+                D9:FE:21:40:6E:94:9E:BC:9B:3D:9C:7D:98:20:19:E5:8C:30:62:B2
+            X509v3 Authority Key Identifier: 
+                D9:FE:21:40:6E:94:9E:BC:9B:3D:9C:7D:98:20:19:E5:8C:30:62:B2
+            X509v3 Basic Constraints: critical
+                CA:TRUE
+            X509v3 Key Usage: critical
+                Digital Signature, Certificate Sign, CRL Sign
+    Signature Algorithm: sha256WithRSAEncryption
+    Signature Value:
+        9e:45:9e:0c:3b:b6:ef:e1:3a:c8:7c:d1:00:3d:cf:e2:ea:06:
+        b5:b2:3a:bb:06:4b:68:7a:d0:23:97:74:a7:2c:f0:08:d8:79:
+        5a:d7:5a:84:8a:d8:12:9a:1b:d9:7d:5c:4d:70:c5:a5:f9:ab:
+        e5:a3:89:89:dd:01:fa:ec:dd:f9:e9:92:97:db:b0:46:42:f3:
+        d3:62:aa:95:fe:31:67:14:69:58:90:0a:aa:0b:ee:37:23:c7:
+        50:51:b4:f5:7e:9e:e3:7b:f7:e4:cc:42:32:2d:49:0c:cb:ff:
+        49:0c:9b:1e:34:fd:6e:6e:96:8a:79:03:b6:6f:db:09:cb:fd:
+        5f:65:14:37:e1:38:f5:f3:61:16:58:e4:b5:6d:0d:0b:04:1b:
+        3f:50:2d:7f:b3:c7:7a:1a:16:80:60:f8:8a:1f:e9:1b:2a:c6:
+        f9:ba:01:1a:69:bf:d2:58:c7:54:57:08:8f:e1:39:60:77:4b:
+        ac:59:84:1a:88:f1:dd:cb:4f:78:d7:e7:e1:33:2d:fc:ee:41:
+        fa:20:b0:be:cb:f7:38:94:c0:e1:d0:85:0f:bb:ed:2c:73:ab:
+        ed:fe:92:76:1a:64:7f:5b:0d:33:09:07:33:7b:06:3f:11:a4:
+        5c:70:3c:85:c0:cf:e3:90:a8:83:77:fa:db:e6:c5:8c:68:67:
+        10:67:a5:52:2d:f0:c4:99:8f:7f:bf:d1:6b:e2:b5:47:d6:d9:
+        d0:85:99:4d:94:9b:0f:4b:8d:ee:00:5a:47:1d:11:03:ac:41:
+        18:af:87:b7:6f:0c:3a:8f:ca:cf:dc:03:c1:a2:09:c8:e5:fd:
+        80:5e:c8:60:42:01:1b:1a:53:5a:bb:37:a6:b7:bc:ba:84:e9:
+        1e:6c:1a:d4:64:da:d4:43:fe:93:8b:4b:f2:2c:79:16:10:d4:
+        93:0b:88:8f:a1:d8:86:14:46:91:47:9b:28:24:ef:57:52:4e:
+        5c:42:9c:aa:f7:49:ec:27:e8:40:1e:b3:a6:89:22:72:9c:f5:
+        0d:33:b4:58:a3:30:3b:dd:d4:6a:54:93:be:1a:4d:f3:93:94:
+        f7:fc:84:0b:3f:84:20:5c:34:03:44:c5:da:ad:bc:0a:c1:02:
+        cf:1e:e5:94:d9:f3:8e:5b:d8:4c:f0:9d:ec:61:17:bb:14:32:
+        54:0c:02:29:93:1e:92:86:f6:7f:ef:e7:92:05:0e:59:dd:99:
+        08:2e:2e:fa:9c:00:52:d3:c5:66:29:e4:a7:97:44:a4:0e:28:
+        81:13:35:c5:f6:6f:64:e6:41:c4:d5:2f:cc:34:45:25:cf:41:
+        00:96:3d:4a:2e:c2:96:98:4f:4e:4a:9c:97:b7:db:1f:92:32:
+        c8:ff:0f:51:6e:d6:ec:09
+-----BEGIN CERTIFICATE-----
+MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNV
+BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw
+IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy
+dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEfMB0GA1UEAwwWVHJ1c3RDb3Ig
+Um9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEyMzExNzI2MzlaMIGk
+MQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEg
+Q2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYD
+VQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRy
+dXN0Q29yIFJvb3RDZXJ0IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
+AoICAQCnIG7CKqJiJJWQdsg4foDSq8GbZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+
+QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9NkRvRUqdw6VC0xK5mC8tkq
+1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1oYxOdqHp
+2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nK
+DOObXUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hape
+az6LMvYHL1cEksr1/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF
+3wP+TfSvPd9cW436cOGlfifHhi5qjxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88
+oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQPeSghYA2FFn3XVDjxklb9tTNM
+g9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+CtgrKAmrhQhJ8Z3
+mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh
+8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAd
+BgNVHQ4EFgQU2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6U
+nrybPZx9mCAZ5YwwYrIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYw
+DQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/hOsh80QA9z+LqBrWyOrsGS2h60COX
+dKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnpkpfbsEZC89NiqpX+
+MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv2wnL
+/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RX
+CI/hOWB3S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYa
+ZH9bDTMJBzN7Bj8RpFxwPIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW
+2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dvDDqPys/cA8GiCcjl/YBeyGBCARsaU1q7
+N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYURpFHmygk71dSTlxCnKr3
+Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANExdqtvArB
+As8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp
+5KeXRKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu
+1uwJ
+-----END CERTIFICATE-----
diff --git a/net/data/ssl/blocklist/5a885db19c01d912c5759388938cafbbdf031ab2d48e91ee15589b42971d039c.pem b/net/data/ssl/blocklist/5a885db19c01d912c5759388938cafbbdf031ab2d48e91ee15589b42971d039c.pem
new file mode 100644
index 0000000..a870112
--- /dev/null
+++ b/net/data/ssl/blocklist/5a885db19c01d912c5759388938cafbbdf031ab2d48e91ee15589b42971d039c.pem
@@ -0,0 +1,85 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            84:82:2c:5f:1c:62:d0:40
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C = PA, ST = Panama, L = Panama City, O = TrustCor Systems S. de R.L., OU = TrustCor Certificate Authority, CN = TrustCor ECA-1
+        Validity
+            Not Before: Feb  4 12:32:33 2016 GMT
+            Not After : Dec 31 17:28:07 2029 GMT
+        Subject: C = PA, ST = Panama, L = Panama City, O = TrustCor Systems S. de R.L., OU = TrustCor Certificate Authority, CN = TrustCor ECA-1
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:cf:8f:e0:11:b5:9f:a8:76:76:db:df:0f:54:ef:
+                    73:63:29:82:ad:47:c6:a3:6b:ed:fe:5f:33:f8:43:
+                    51:e9:1a:33:91:31:17:a0:74:c4:d4:a7:01:e6:b2:
+                    92:3e:6a:9d:ed:0e:f9:74:98:40:d3:3f:03:80:06:
+                    82:40:e8:b1:e2:a7:51:a7:1d:83:26:6b:ab:de:fa:
+                    17:91:2b:d8:c6:ac:1e:b1:9e:19:01:d5:97:a6:ea:
+                    0d:b7:c4:55:1f:27:7c:d2:08:d5:76:1f:29:15:87:
+                    40:39:dd:38:45:11:75:d0:9a:a7:34:e0:bf:cd:c8:
+                    52:1d:b9:47:7e:0d:b8:bb:c6:0c:f6:73:57:16:5a:
+                    7e:43:91:1f:55:3a:c6:6d:44:04:aa:9c:a9:9c:a7:
+                    4c:89:17:83:ae:a3:04:5e:52:80:8b:1e:12:25:11:
+                    19:d7:0c:7d:7d:31:44:41:ea:db:af:b0:1c:ef:81:
+                    d0:2c:c5:9a:21:9b:3d:ed:42:3b:50:26:f2:ec:ce:
+                    71:61:06:62:21:54:4e:7f:c1:9d:3e:7f:20:8c:80:
+                    cb:2a:d8:97:62:c8:83:33:91:7d:b0:a2:5a:0f:57:
+                    e8:3b:cc:f2:25:b2:d4:7c:2f:ec:4d:c6:a1:3a:15:
+                    7a:e7:b6:5d:35:f5:f6:48:4a:36:45:66:d4:ba:98:
+                    58:c1
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Subject Key Identifier: 
+                44:9E:48:F5:CC:6D:48:D4:A0:4B:7F:FE:59:24:2F:83:97:99:9A:86
+            X509v3 Authority Key Identifier: 
+                44:9E:48:F5:CC:6D:48:D4:A0:4B:7F:FE:59:24:2F:83:97:99:9A:86
+            X509v3 Basic Constraints: critical
+                CA:TRUE
+            X509v3 Key Usage: critical
+                Digital Signature, Certificate Sign, CRL Sign
+    Signature Algorithm: sha256WithRSAEncryption
+    Signature Value:
+        05:3e:35:5c:15:70:9b:c9:c7:73:61:6f:72:2b:d4:c2:8f:f2:
+        43:5d:02:ce:c4:94:b9:94:11:83:67:5d:e2:67:6c:75:76:bf:
+        bb:0c:aa:36:c6:ad:47:93:63:dc:1e:7e:d6:de:2e:fe:e9:19:
+        32:38:03:7f:14:f6:00:73:2c:59:b1:21:06:e1:fb:ac:18:95:
+        0c:a3:ff:99:96:f7:2b:27:9b:d5:24:cc:1d:dd:c1:3a:e0:98:
+        44:b0:c4:e4:3e:77:b1:73:a9:64:2c:f6:1c:01:7c:3f:5d:45:
+        85:c0:85:e7:25:8f:95:dc:17:f3:3c:9f:1a:6e:b0:ca:e3:1d:
+        2a:e9:4c:63:fa:24:61:62:d6:da:7e:b6:1c:6c:f5:02:1d:d4:
+        2a:dd:55:90:eb:2a:11:47:3c:2e:5e:74:b2:82:22:a5:7d:53:
+        1f:45:ec:27:91:7d:e7:22:16:e8:c0:68:36:d8:c6:f1:4f:80:
+        44:32:f9:e1:d1:d1:1d:aa:de:a8:ab:9c:04:af:ad:20:0e:64:
+        98:4d:a5:6b:c0:48:58:96:69:4d:dc:07:8c:51:93:a2:df:9f:
+        0f:3d:8b:60:b4:82:8d:aa:08:4e:62:45:e0:f9:0b:d2:e0:e0:
+        3c:5b:de:5c:71:27:25:c2:e6:03:81:8b:10:53:e3:c7:55:a2:
+        b4:9f:d7:e6
+-----BEGIN CERTIFICATE-----
+MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD
+VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk
+MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U
+cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxFzAVBgNVBAMMDlRydXN0Q29y
+IEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3MjgwN1owgZwxCzAJBgNV
+BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw
+IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy
+dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3Ig
+RUNBLTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb
+3w9U73NjKYKtR8aja+3+XzP4Q1HpGjORMRegdMTUpwHmspI+ap3tDvl0mEDTPwOA
+BoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23xFUfJ3zSCNV2HykVh0A5
+3ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmcp0yJF4Ou
+owReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/
+wZ0+fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZF
+ZtS6mFjBAgMBAAGjYzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAf
+BgNVHSMEGDAWgBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/
+MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEABT41XBVwm8nHc2Fv
+civUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u/ukZMjgDfxT2
+AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F
+hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50
+soIipX1TH0XsJ5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BI
+WJZpTdwHjFGTot+fDz2LYLSCjaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1Wi
+tJ/X5g==
+-----END CERTIFICATE-----
diff --git a/net/data/ssl/blocklist/README.md b/net/data/ssl/blocklist/README.md
index 3214d9f..d335d26 100644
--- a/net/data/ssl/blocklist/README.md
+++ b/net/data/ssl/blocklist/README.md
@@ -145,6 +145,17 @@
 
   * [82a4cedbc7f61ce5cb04482aa27ea3145bb0cea58ab63ba1931a1654bfbdbb4f.pem](82a4cedbc7f61ce5cb04482aa27ea3145bb0cea58ab63ba1931a1654bfbdbb4f.pem)
 
+### TrustCor
+
+To coincide with the release of M111, the Chrome Root Program announced a
+distrust of the CA Owner "TrustCor".
+
+For details, see <https://groups.google.com/a/mozilla.org/g/dev-security-policy/c/oxX69KFvsm4/m/PKpJf5W6AQAJ>
+
+  * [5a885db19c01d912c5759388938cafbbdf031ab2d48e91ee15589b42971d039c.pem](5a885db19c01d912c5759388938cafbbdf031ab2d48e91ee15589b42971d039c.pem)
+  * [0753e940378c1bd5e3836e395daea5cb839e5046f1bd0eae1951cf10fec7c965.pem](0753e940378c1bd5e3836e395daea5cb839e5046f1bd0eae1951cf10fec7c965.pem)
+  * [d40e9c86cd8fe468c1776959f49ea774fa548684b6c406f3909261f4dce2575c.pem](d40e9c86cd8fe468c1776959f49ea774fa548684b6c406f3909261f4dce2575c.pem)
+
 ### Trustwave
 
 For details, see <https://www.trustwave.com/Resources/SpiderLabs-Blog/Clarifying-The-Trustwave-CA-Policy-Update/>
diff --git a/net/data/ssl/blocklist/d40e9c86cd8fe468c1776959f49ea774fa548684b6c406f3909261f4dce2575c.pem b/net/data/ssl/blocklist/d40e9c86cd8fe468c1776959f49ea774fa548684b6c406f3909261f4dce2575c.pem
new file mode 100644
index 0000000..aab3e3de
--- /dev/null
+++ b/net/data/ssl/blocklist/d40e9c86cd8fe468c1776959f49ea774fa548684b6c406f3909261f4dce2575c.pem
@@ -0,0 +1,85 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            da:9b:ec:71:f3:03:b0:19
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C = PA, ST = Panama, L = Panama City, O = TrustCor Systems S. de R.L., OU = TrustCor Certificate Authority, CN = TrustCor RootCert CA-1
+        Validity
+            Not Before: Feb  4 12:32:16 2016 GMT
+            Not After : Dec 31 17:23:16 2029 GMT
+        Subject: C = PA, ST = Panama, L = Panama City, O = TrustCor Systems S. de R.L., OU = TrustCor Certificate Authority, CN = TrustCor RootCert CA-1
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:bf:8e:b7:95:e2:c2:26:12:6b:33:19:c7:40:58:
+                    0a:ab:59:aa:8d:00:a3:fc:80:c7:50:7b:8e:d4:20:
+                    26:ba:32:12:d8:23:54:49:25:10:22:98:9d:46:d2:
+                    c1:c9:9e:4e:1b:2e:2c:0e:38:f3:1a:25:68:1c:a6:
+                    5a:05:e6:1e:8b:48:bf:98:96:74:3e:69:ca:e9:b5:
+                    78:a5:06:bc:d5:00:5e:09:0a:f2:27:7a:52:fc:2d:
+                    d5:b1:ea:b4:89:61:24:f3:1a:13:db:a9:cf:52:ed:
+                    0c:24:ba:b9:9e:ec:7e:00:74:fa:93:ad:6c:29:92:
+                    ae:51:b4:bb:d3:57:bf:b3:f3:a8:8d:9c:f4:24:4b:
+                    2a:d6:99:9e:f4:9e:fe:c0:7e:42:3a:e7:0b:95:53:
+                    da:b7:68:0e:90:4c:fb:70:3f:8f:4a:2c:94:f3:26:
+                    dd:63:69:a9:94:d8:10:4e:c5:47:08:90:99:1b:17:
+                    4d:b9:6c:6e:ef:60:95:11:8e:21:80:b5:bd:a0:73:
+                    d8:d0:b2:77:c4:45:ea:5a:26:fb:66:76:76:f8:06:
+                    1f:61:6d:0f:55:c5:83:b7:10:56:72:06:07:a5:f3:
+                    b1:1a:03:05:64:0e:9d:5a:8a:d6:86:70:1b:24:de:
+                    fe:28:8a:2b:d0:6a:b0:fc:7a:a2:dc:b2:79:0e:8b:
+                    65:0f
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Subject Key Identifier: 
+                EE:6B:49:3C:7A:3F:0D:E3:B1:09:B7:8A:C8:AB:19:9F:73:33:50:E7
+            X509v3 Authority Key Identifier: 
+                EE:6B:49:3C:7A:3F:0D:E3:B1:09:B7:8A:C8:AB:19:9F:73:33:50:E7
+            X509v3 Basic Constraints: critical
+                CA:TRUE
+            X509v3 Key Usage: critical
+                Digital Signature, Certificate Sign, CRL Sign
+    Signature Algorithm: sha256WithRSAEncryption
+    Signature Value:
+        25:18:d4:91:8f:13:ee:8f:1e:1d:11:53:da:2d:44:29:19:a0:
+        1e:6b:31:9e:4d:0e:9e:ad:3d:5c:41:6f:95:2b:24:a1:79:98:
+        3a:38:36:fb:bb:66:9e:48:ff:90:90:ef:3d:d4:b8:9b:b4:87:
+        75:3f:20:9b:ce:72:cf:a1:55:c1:4d:64:a2:19:06:a1:07:33:
+        0c:0b:29:e5:f1:ea:ab:a3:ec:b5:0a:74:90:c7:7d:72:f2:d7:
+        5c:9f:91:ef:91:8b:b7:dc:ed:66:a2:cf:8e:66:3b:bc:9f:3a:
+        02:e0:27:dd:16:98:c0:95:d4:0a:a4:e4:81:9a:75:94:35:9c:
+        90:5f:88:37:06:ad:59:95:0a:b0:d1:67:d3:19:ca:89:e7:32:
+        5a:36:1c:3e:82:a8:5a:93:be:c6:d0:64:91:b6:cf:d9:b6:18:
+        cf:db:7e:d2:65:a3:a6:c4:8e:17:31:c1:fb:7e:76:db:d3:85:
+        e3:58:b2:77:7a:76:3b:6c:2f:50:1c:e7:db:f6:67:79:1f:f5:
+        82:95:9a:07:a7:14:af:8f:dc:28:21:67:09:d2:d6:4d:5a:1c:
+        19:1c:8e:77:5c:c3:94:24:3d:32:6b:4b:7e:d4:78:94:83:be:
+        37:4d:ce:5f:c7:1e:4e:3c:e0:89:33:95:0b:0f:a5:32:d6:3c:
+        5a:79:2c:19
+-----BEGIN CERTIFICATE-----
+MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYD
+VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk
+MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U
+cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29y
+IFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkxMjMxMTcyMzE2WjCB
+pDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFuYW1h
+IENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUG
+A1UECwweVHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZU
+cnVzdENvciBSb290Q2VydCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEAv463leLCJhJrMxnHQFgKq1mqjQCj/IDHUHuO1CAmujIS2CNUSSUQIpid
+RtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4pQa81QBeCQryJ3pS/C3V
+seq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0JEsq1pme
+9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CV
+EY4hgLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorW
+hnAbJN7+KIor0Gqw/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/
+DeOxCbeKyKsZn3MzUOcwHwYDVR0jBBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcw
+DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD
+ggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5mDo4Nvu7Zp5I
+/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf
+ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZ
+yonnMlo2HD6CqFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djts
+L1Ac59v2Z3kf9YKVmgenFK+P3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdN
+zl/HHk484IkzlQsPpTLWPFp5LBk=
+-----END CERTIFICATE-----
diff --git a/net/http/http_no_vary_search_data.cc b/net/http/http_no_vary_search_data.cc
index 421c557..25dae355 100644
--- a/net/http/http_no_vary_search_data.cc
+++ b/net/http/http_no_vary_search_data.cc
@@ -7,6 +7,7 @@
 #include "base/containers/contains.h"
 #include "base/containers/flat_set.h"
 #include "net/base/url_search_params.h"
+#include "net/base/url_util.h"
 #include "net/http/http_response_headers.h"
 #include "net/http/structured_headers.h"
 #include "url/gurl.h"
@@ -23,7 +24,7 @@
   for (const auto& item : items) {
     if (!item.item.is_string())
       return absl::nullopt;
-    keys.push_back(item.item.GetString());
+    keys.push_back(UnescapePercentEncodedUrl(item.item.GetString()));
   }
   return keys;
 }
diff --git a/net/http/http_no_vary_search_data_unittest.cc b/net/http/http_no_vary_search_data_unittest.cc
index 022d193..3aaa7e7 100644
--- a/net/http/http_no_vary_search_data_unittest.cc
+++ b/net/http/http_no_vary_search_data_unittest.cc
@@ -320,6 +320,38 @@
         true,        // expected_vary_on_key_order
         true,        // expected_vary_by_default
     },
+    // params set to a list of strings with one non-ASCII character.
+    {
+        "HTTP/1.1 200 OK\r\n"
+        R"(No-Vary-Search: params=("%C2%A2"))"
+        "\r\n\r\n",  // raw_headers
+        {"¢"},       // expected_no_vary_params
+        {},          // expected_vary_params
+        true,        // expected_vary_on_key_order
+        true,        // expected_vary_by_default
+    },
+    // params set to a list of strings with one ASCII and one non-ASCII
+    // character.
+    {
+        "HTTP/1.1 200 OK\r\n"
+        R"(No-Vary-Search: params=("c%C2%A2"))"
+        "\r\n\r\n",  // raw_headers
+        {"c¢"},      // expected_no_vary_params
+        {},          // expected_vary_params
+        true,        // expected_vary_on_key_order
+        true,        // expected_vary_by_default
+    },
+    // params set to a list of strings with one space and one non-ASCII
+    // character.
+    {
+        "HTTP/1.1 200 OK\r\n"
+        R"(No-Vary-Search: params=("+%C2%A2"))"
+        "\r\n\r\n",  // raw_headers
+        {" ¢"},      // expected_no_vary_params
+        {},          // expected_vary_params
+        true,        // expected_vary_on_key_order
+        true,        // expected_vary_by_default
+    },
     // params set to true.
     {
         "HTTP/1.1 200 OK\r\n"
@@ -371,6 +403,29 @@
         true,        // expected_vary_on_key_order
         false,       // expected_vary_by_default
     },
+    // Vary on all with one excepted non-ASCII search param.
+    {
+        "HTTP/1.1 200 OK\r\n"
+        "No-Vary-Search: params\r\n"
+        R"(No-Vary-Search: except=("%C2%A2"))"
+        "\r\n\r\n",  // raw_headers
+        {},          // expected_no_vary_params
+        {"¢"},       // expected_vary_params
+        true,        // expected_vary_on_key_order
+        false,       // expected_vary_by_default
+    },
+    // Vary on all with one excepted search param that includes non-ASCII
+    // character.
+    {
+        "HTTP/1.1 200 OK\r\n"
+        "No-Vary-Search: params\r\n"
+        R"(No-Vary-Search: except=("c+%C2%A2"))"
+        "\r\n\r\n",  // raw_headers
+        {},          // expected_no_vary_params
+        {"c ¢"},     // expected_vary_params
+        true,        // expected_vary_on_key_order
+        false,       // expected_vary_by_default
+    },
     // Vary on all with one excepted search param. Set params as
     // part of the same header line.
     {
@@ -681,8 +736,7 @@
   const bool expected_match;
 };
 
-TEST(HttpNoVarySearchCompare,
-     CheckUrlEqualityByNoVarySearchWithSpecialCharacters) {
+TEST(HttpNoVarySearchCompare, CheckUrlEqualityWithSpecialCharacters) {
   // Use special characters in both `keys` and `values`.
   const base::flat_map<std::string, std::string> percent_encoding = {
       {"!", "%21"},    {"#", "%23"},    {"$", "%24"},    {"%", "%25"},
@@ -693,7 +747,6 @@
       {"@", "%40"},    {"[", "%5B"},    {"]", R"(%5D)"}, {"^", R"(%5E)"},
       {"_", R"(%5F)"}, {"`", "%60"},    {"{", "%7B"},    {"|", R"(%7C)"},
       {"}", R"(%7D)"}, {"~", R"(%7E)"}, {"", ""}};
-
   const base::StringPiece raw_headers =
       "HTTP/1.1 200 OK\r\n"
       R"(No-Vary-Search: params=("c"))"
@@ -736,6 +789,70 @@
   }
 }
 
+constexpr std::pair<base::StringPiece, base::StringPiece>
+    kPercentEncodedNonAsciiKeys[] = {
+        {"¢", R"(%C2%A2)"},
+        {"¢ ¢", R"(%C2%A2+%C2%A2)"},
+        {"é 気", R"(%C3%A9+%E6%B0%97)"},
+        {"é", R"(%C3%A9)"},
+        {"気", R"(%E6%B0%97)"},
+        {"ぁ", R"(%E3%81%81)"},
+        {"𐨀", R"(%F0%90%A8%80)"},
+};
+
+TEST(HttpNoVarySearchCompare,
+     CheckUrlEqualityWithPercentEncodedNonASCIICharactersExcept) {
+  for (const auto& [key, value] : kPercentEncodedNonAsciiKeys) {
+    std::string request_url_template = R"(https://a.test/index.html?$key=c)";
+    std::string cached_url_template = R"(https://a.test/index.html?c=3&$key=c)";
+    base::ReplaceSubstringsAfterOffset(&request_url_template, 0, "$key", key);
+    base::ReplaceSubstringsAfterOffset(&cached_url_template, 0, "$key", key);
+    std::string header_template =
+        "HTTP/1.1 200 OK\r\n"
+        R"(No-Vary-Search: params, except=("$key"))"
+        "\r\n\r\n";
+    base::ReplaceSubstringsAfterOffset(&header_template, 0, "$key", value);
+
+    const auto parsed_header = base::MakeRefCounted<HttpResponseHeaders>(
+        net::HttpUtil::AssembleRawHeaders(header_template));
+    const auto no_vary_search_data_special_char =
+        HttpNoVarySearchData::ParseFromHeaders(*parsed_header).value();
+
+    EXPECT_TRUE(no_vary_search_data_special_char.AreEquivalent(
+        GURL(request_url_template), GURL(cached_url_template)))
+        << "request_url = " << request_url_template
+        << " cached_url = " << cached_url_template
+        << " headers = " << header_template;
+  }
+}
+
+TEST(HttpNoVarySearchCompare,
+     CheckUrlEqualityWithPercentEncodedNonASCIICharacters) {
+  for (const auto& [key, value] : kPercentEncodedNonAsciiKeys) {
+    std::string request_url_template =
+        R"(https://a.test/index.html?a=2&$key=c)";
+    std::string cached_url_template = R"(https://a.test/index.html?$key=d&a=2)";
+    base::ReplaceSubstringsAfterOffset(&request_url_template, 0, "$key", key);
+    base::ReplaceSubstringsAfterOffset(&cached_url_template, 0, "$key", key);
+    std::string header_template =
+        "HTTP/1.1 200 OK\r\n"
+        R"(No-Vary-Search: params=("$key"))"
+        "\r\n\r\n";
+    base::ReplaceSubstringsAfterOffset(&header_template, 0, "$key", value);
+
+    const auto parsed_header = base::MakeRefCounted<HttpResponseHeaders>(
+        net::HttpUtil::AssembleRawHeaders(header_template));
+    const auto no_vary_search_data_special_char =
+        HttpNoVarySearchData::ParseFromHeaders(*parsed_header).value();
+
+    EXPECT_TRUE(no_vary_search_data_special_char.AreEquivalent(
+        GURL(request_url_template), GURL(cached_url_template)))
+        << "request_url = " << request_url_template
+        << " cached_url = " << cached_url_template
+        << " headers = " << header_template;
+  }
+}
+
 class HttpNoVarySearchCompare
     : public ::testing::Test,
       public ::testing::WithParamInterface<NoVarySearchCompareTestData> {};
@@ -938,6 +1055,46 @@
      R"(No-Vary-Search: params=("c"))"
      "\r\n\r\n",
      true},
+    // Add test when there is a param with key starting with a percent encoded
+    // space (+).
+    {GURL(R"(https://a.test/index.html?+a=3)"),
+     GURL(R"(https://a.test/index.html?+a=2)"),
+     "HTTP/1.1 200 OK\r\n"
+     R"(No-Vary-Search: params=("+a"))"
+     "\r\n\r\n",
+     true},
+    // Add test when there is a param with key starting with a percent encoded
+    // space (+) and gets compared with same key without the leading space.
+    {GURL(R"(https://a.test/index.html?+a=3)"),
+     GURL(R"(https://a.test/index.html?a=2)"),
+     "HTTP/1.1 200 OK\r\n"
+     R"(No-Vary-Search: params=("+a"))"
+     "\r\n\r\n",
+     false},
+    // Add test for when there are different representations of the character é
+    // and we are ignoring that key.
+    {GURL(R"(https://a.test/index.html?%C3%A9=g&a=2&c=4&é=b)"),
+     GURL(R"(https://a.test/index.html?a=2&é=f&c=4&d=7&é=b)"),
+     "HTTP/1.1 200 OK\r\n"
+     R"(No-Vary-Search: params=("d" "%C3%A9"))"
+     "\r\n\r\n",
+     true},
+    // Add test for when there are different representations of the character é
+    // and we are not ignoring that key.
+    {GURL(R"(https://a.test/index.html?%C3%A9=f&a=2&c=4&é=b)"),
+     GURL(R"(https://a.test/index.html?a=2&é=f&c=4&d=7&é=b)"),
+     "HTTP/1.1 200 OK\r\n"
+     R"(No-Vary-Search: params, except=("%C3%A9"))"
+     "\r\n\r\n",
+     true},
+    // Add test for when there are different representations of the character é
+    // and we are not ignoring that key.
+    {GURL(R"(https://a.test/index.html?%C3%A9=g&a=2&c=4&é=b)"),
+     GURL(R"(https://a.test/index.html?a=2&é=f&c=4&d=7&é=b)"),
+     "HTTP/1.1 200 OK\r\n"
+     R"(No-Vary-Search: params, except=("%C3%A9"))"
+     "\r\n\r\n",
+     false},
 };
 
 INSTANTIATE_TEST_SUITE_P(HttpNoVarySearchCompare,
diff --git a/remoting/codec/webrtc_video_encoder.cc b/remoting/codec/webrtc_video_encoder.cc
index 8f7386bc..1fb5ef11 100644
--- a/remoting/codec/webrtc_video_encoder.cc
+++ b/remoting/codec/webrtc_video_encoder.cc
@@ -18,7 +18,9 @@
 // static
 int WebrtcVideoEncoder::GetEncoderThreadCount(int frame_width) {
   int thread_num;
-  if (frame_width >= 3840) {
+  if (frame_width >= 5120) {
+    thread_num = 32;
+  } else if (frame_width >= 3840) {
     thread_num = 16;
   } else if (frame_width >= 2560) {
     thread_num = 8;
diff --git a/remoting/codec/webrtc_video_encoder_av1.cc b/remoting/codec/webrtc_video_encoder_av1.cc
index 2407a002..89949e8 100644
--- a/remoting/codec/webrtc_video_encoder_av1.cc
+++ b/remoting/codec/webrtc_video_encoder_av1.cc
@@ -92,6 +92,24 @@
   if (config_.g_threads > 1) {
     error = aom_codec_control(codec.get(), AV1E_SET_ROW_MT, 1);
     DCHECK_EQ(error, AOM_CODEC_OK) << "Failed to set AV1E_SET_ROW_MT";
+
+    // Use a smaller superblock size when allocating > 16 threads.
+    if (config_.g_threads > 16) {
+      // The default value for AV1E_SET_SUPERBLOCK_SIZE is
+      // AOM_SUPERBLOCK_SIZE_DYNAMIC which uses 64x64 blocks for resolutions of
+      // 720px or lower and 128x128 for resolutions above that. When testing
+      // with display resolutions higher than 3840x2160 (4K), we found that
+      // increasing the number of threads from 16 to 32 increased performance
+      // for VP9 but performance decreased with AV1. The codec team investigated
+      // and suggested adjusting the superblock size down to 64x64 to increase
+      // the amount of parallelism.  This solution increased performance for 5K
+      // displays and put it around the level of what we see for a 4K display.
+      // See https://crbug.com/aomedia/3363 for more info.
+      error = aom_codec_control(codec.get(), AV1E_SET_SUPERBLOCK_SIZE,
+                                AOM_SUPERBLOCK_SIZE_64X64);
+      DCHECK_EQ(error, AOM_CODEC_OK)
+          << "Failed to set AV1E_SET_SUPERBLOCK_SIZE";
+    }
   }
 
   // The param used to set the tile columns and tile rows is in log2 so 0 is ok.
diff --git a/sandbox/policy/mac/sandbox_mac.mm b/sandbox/policy/mac/sandbox_mac.mm
index d709edc..99a89b0 100644
--- a/sandbox/policy/mac/sandbox_mac.mm
+++ b/sandbox/policy/mac/sandbox_mac.mm
@@ -25,7 +25,9 @@
 #include "sandbox/policy/mac/nacl_loader.sb.h"
 #include "sandbox/policy/mac/network.sb.h"
 #include "sandbox/policy/mac/ppapi.sb.h"
+#if BUILDFLAG(ENABLE_OOP_PRINTING)
 #include "sandbox/policy/mac/print_backend.sb.h"
+#endif
 #include "sandbox/policy/mac/print_compositor.sb.h"
 #include "sandbox/policy/mac/renderer.sb.h"
 #if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
@@ -81,7 +83,7 @@
       profile += kSeatbeltPolicyString_ppapi;
       break;
 #endif
-#if BUILDFLAG(ENABLE_PRINTING)
+#if BUILDFLAG(ENABLE_OOP_PRINTING)
     case sandbox::mojom::Sandbox::kPrintBackend:
       profile += kSeatbeltPolicyString_print_backend;
       break;
diff --git a/services/cert_verifier/cert_verifier_creation.cc b/services/cert_verifier/cert_verifier_creation.cc
index 85f8065..d09b13b 100644
--- a/services/cert_verifier/cert_verifier_creation.cc
+++ b/services/cert_verifier/cert_verifier_creation.cc
@@ -142,6 +142,13 @@
     trust_store =
         net::CreateSslSystemTrustStoreChromeRoot(std::move(chrome_root));
 #endif
+#if BUILDFLAG(IS_WIN)
+    // Start initialization of TrustStoreWin on a separate thread if it hasn't
+    // been done already. We do this here instead of in the TrustStoreWin
+    // constructor to avoid any unnecessary threading in unit tests that don't
+    // use threads otherwise.
+    net::InitializeTrustStoreWinSystem();
+#endif
     return net::CreateCertVerifyProcBuiltin(std::move(cert_net_fetcher),
                                             std::move(trust_store));
   }
diff --git a/services/network/public/cpp/features.cc b/services/network/public/cpp/features.cc
index 14167933..1502343b 100644
--- a/services/network/public/cpp/features.cc
+++ b/services/network/public/cpp/features.cc
@@ -306,6 +306,9 @@
              "PrefetchDNSWithURL",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
+constexpr base::FeatureParam<bool> kPrefetchDNSWithURLAllAnchorElements{
+    &kPrefetchDNSWithURL, "prefetch_dns_all_anchor_elements", true};
+
 // Preconnect to a new origin right when a redirect starts.
 BASE_FEATURE(kPreconnectOnRedirect,
              "PreconnectOnRedirect",
diff --git a/services/network/public/cpp/features.h b/services/network/public/cpp/features.h
index 85c9879..1c6712b 100644
--- a/services/network/public/cpp/features.h
+++ b/services/network/public/cpp/features.h
@@ -95,6 +95,9 @@
 
 COMPONENT_EXPORT(NETWORK_CPP) BASE_DECLARE_FEATURE(kPrefetchDNSWithURL);
 
+COMPONENT_EXPORT(NETWORK_CPP)
+extern const base::FeatureParam<bool> kPrefetchDNSWithURLAllAnchorElements;
+
 COMPONENT_EXPORT(NETWORK_CPP) BASE_DECLARE_FEATURE(kPreconnectOnRedirect);
 
 COMPONENT_EXPORT(NETWORK_CPP)
diff --git a/styleguide/java/java.md b/styleguide/java/java.md
index f6415f0..68643dc 100644
--- a/styleguide/java/java.md
+++ b/styleguide/java/java.md
@@ -15,7 +15,7 @@
 
 [TOC]
 
-## Java 10 language Features
+## Java 10 Language Features
 
 ### Type deduction using `var`
 
@@ -38,51 +38,42 @@
 ```
 
 ## Java 8 Language Features
-[Desugar](https://github.com/bazelbuild/bazel/blob/master/src/tools/android/java/com/google/devtools/build/android/desugar/Desugar.java)
-is used to rewrite some Java 7 & 8 language constructs in a way that is
-compatible with Java 6 (and thus all Android versions). Use of
-[these features](https://developer.android.com/studio/write/java8-support)
-is encouraged, but there are some gotchas:
+[D8] is used to rewrite some Java 7 & 8 language constructs in a way that is
+compatible with Java 6 (and thus all Android versions). Use of [these features]
+is encouraged.
 
-### Default Interface Methods
- * Desugar makes default interface methods work by copy & pasting the default
-   implementations into all implementing classes.
- * This technique is fine for infrequently-used interfaces, but should be
-   avoided (e.g. via a base class) if it noticeably increases method count.
+[D8]: https://developer.android.com/studio/command-line/d8
+[these features]: https://developer.android.com/studio/write/java8-support
 
-### Lambdas and Method References
- * These are syntactic sugar for creating anonymous inner classes.
- * Use them only where the cost of an extra class & method definition is
-   justified.
+## Java Library APIs
 
-### try-with-resources
- * Some library classes do not implement Closeable on older platform APIs.
-   Runtime exceptions are thrown if you use them with a try-with-resources.
-   Do not use the following classes in a try-with-resources:
-   * java.util.zip.ZipFile (implemented in API 19)
-   * java.net.Socket (implemented in API 19)
+Android provides the ability to bundle copies of `java.` APIs alongside
+application code, known as [Java Library Desugaring]. However, since this
+bundling comes with a performance cost, Chrome does not use it. Treat `java.`
+APIs the same as you would `android.` ones and guard them with
+`Build.VERSION.SDK_INT` checks [when necessary]. The one exception is if the
+method is [directly backported by D8] (these are okay to use, since they are
+lightweight). Android Lint will fail if you try to use an API without a
+corresponding `Build.VERSION.SDK_INT` guard or `@RequiresApi` annotation.
+
+[Java Library Desugaring]: https://developer.android.com/studio/write/java8-support-table
+[when necessary]: https://developer.android.com/reference/packages
+[directly backported by D8]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/r8/backported_methods.txt
 
 ## Other Language Features & APIs
 
 ### Exceptions
-* As with the Android style guide, we discourage overly broad catches via
-`Exception` / `Throwable` / `RuntimeException`.
-  * If you need to have a broad catch expression, use a comment to explain why.
-* Catching multiple exceptions in one line is fine.
+We discourage overly broad catches via `Throwable`, `Exception`, or
+`RuntimeException`, except when dealing with `RemoteException` or similar
+system APIs.
+ * There have been many cases of crashes caused by `IllegalStateException` /
+   `IllegalArgumentException` / `SecurityException` being thrown where only
+   `RemoteException` was being caught. In these cases, use
+   `catch (RemoteException | RuntimeException e)`.
+ * For all broad catch expressions, add a comment to explain why.
 
-It is OK to do:
-```java
-try {
-  somethingThatThrowsIOException(filePath);
-  somethingThatThrowsParseException(filePath);
-} catch (IOException | ParseException e) {
-  Log.w(TAG, "Failed to read: %s", filePath, e);
-}
-```
+Avoid adding messages to exceptions that do not aid in debugging. For example:
 
-* Avoid adding messages to exceptions that do not aid in debugging.
-
-For example:
 ```java
 try {
   somethingThatThrowsIOException();
diff --git a/testing/buildbot/chrome.json b/testing/buildbot/chrome.json
index a27a343..ba74294 100644
--- a/testing/buildbot/chrome.json
+++ b/testing/buildbot/chrome.json
@@ -1854,7 +1854,7 @@
       {
         "args": [],
         "cros_board": "dedede",
-        "cros_img": "dedede-release/R111-15308.0.0",
+        "cros_img": "dedede-release/R111-15310.0.0",
         "name": "lacros_all_tast_tests DEDEDE_RELEASE_LKGM",
         "resultdb": {
           "enable": true,
@@ -1886,7 +1886,7 @@
       {
         "args": [],
         "cros_board": "dedede",
-        "cros_img": "dedede-release/R109-15236.35.0",
+        "cros_img": "dedede-release/R110-15278.29.0",
         "name": "lacros_all_tast_tests DEDEDE_RELEASE_BETA",
         "resultdb": {
           "enable": true,
@@ -1918,7 +1918,7 @@
       {
         "args": [],
         "cros_board": "eve",
-        "cros_img": "eve-release/R111-15308.0.0",
+        "cros_img": "eve-release/R111-15310.0.0",
         "name": "lacros_all_tast_tests EVE_RELEASE_LKGM",
         "resultdb": {
           "enable": true,
@@ -2061,7 +2061,7 @@
       {
         "args": [],
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-release/R111-15308.0.0",
+        "cros_img": "jacuzzi-release/R111-15310.0.0",
         "name": "lacros_all_tast_tests JACUZZI_RELEASE_LKGM",
         "resultdb": {
           "enable": true,
@@ -2093,7 +2093,7 @@
       {
         "args": [],
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-release/R109-15236.35.0",
+        "cros_img": "jacuzzi-release/R110-15278.29.0",
         "name": "lacros_all_tast_tests JACUZZI_RELEASE_BETA",
         "resultdb": {
           "enable": true,
@@ -2166,7 +2166,7 @@
       {
         "args": [],
         "cros_board": "herobrine",
-        "cros_img": "herobrine-release/R111-15308.0.0",
+        "cros_img": "herobrine-release/R111-15310.0.0",
         "name": "lacros_fyi_tast_tests HEROBRINE_RELEASE_LKGM",
         "resultdb": {
           "enable": true,
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index 01d5c0b..534dfe4 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -5839,9 +5839,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5536.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5537.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 111.0.5536.0",
+        "description": "Run with ash-chrome version 111.0.5537.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -5853,8 +5853,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v111.0.5536.0",
-              "revision": "version:111.0.5536.0"
+              "location": "lacros_version_skew_tests_v111.0.5537.0",
+              "revision": "version:111.0.5537.0"
             }
           ],
           "dimension_sets": [
@@ -6010,9 +6010,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5536.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5537.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 111.0.5536.0",
+        "description": "Run with ash-chrome version 111.0.5537.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -6024,8 +6024,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v111.0.5536.0",
-              "revision": "version:111.0.5536.0"
+              "location": "lacros_version_skew_tests_v111.0.5537.0",
+              "revision": "version:111.0.5537.0"
             }
           ],
           "dimension_sets": [
@@ -6162,9 +6162,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5536.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5537.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 111.0.5536.0",
+        "description": "Run with ash-chrome version 111.0.5537.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -6176,8 +6176,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v111.0.5536.0",
-              "revision": "version:111.0.5536.0"
+              "location": "lacros_version_skew_tests_v111.0.5537.0",
+              "revision": "version:111.0.5537.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index bf1eb91..1f814bb 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -83297,9 +83297,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5536.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5537.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 111.0.5536.0",
+        "description": "Run with ash-chrome version 111.0.5537.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -83311,8 +83311,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v111.0.5536.0",
-              "revision": "version:111.0.5536.0"
+              "location": "lacros_version_skew_tests_v111.0.5537.0",
+              "revision": "version:111.0.5537.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -83438,9 +83438,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5536.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5537.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 111.0.5536.0",
+        "description": "Run with ash-chrome version 111.0.5537.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -83452,8 +83452,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v111.0.5536.0",
-              "revision": "version:111.0.5536.0"
+              "location": "lacros_version_skew_tests_v111.0.5537.0",
+              "revision": "version:111.0.5537.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -83565,9 +83565,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5536.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5537.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 111.0.5536.0",
+        "description": "Run with ash-chrome version 111.0.5537.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -83579,8 +83579,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v111.0.5536.0",
-              "revision": "version:111.0.5536.0"
+              "location": "lacros_version_skew_tests_v111.0.5537.0",
+              "revision": "version:111.0.5537.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -84913,9 +84913,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5536.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5537.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 111.0.5536.0",
+        "description": "Run with ash-chrome version 111.0.5537.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -84926,8 +84926,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v111.0.5536.0",
-              "revision": "version:111.0.5536.0"
+              "location": "lacros_version_skew_tests_v111.0.5537.0",
+              "revision": "version:111.0.5537.0"
             }
           ],
           "dimension_sets": [
@@ -85084,9 +85084,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5536.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5537.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 111.0.5536.0",
+        "description": "Run with ash-chrome version 111.0.5537.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -85097,8 +85097,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v111.0.5536.0",
-              "revision": "version:111.0.5536.0"
+              "location": "lacros_version_skew_tests_v111.0.5537.0",
+              "revision": "version:111.0.5537.0"
             }
           ],
           "dimension_sets": [
@@ -85236,9 +85236,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5536.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5537.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 111.0.5536.0",
+        "description": "Run with ash-chrome version 111.0.5537.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -85249,8 +85249,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v111.0.5536.0",
-              "revision": "version:111.0.5536.0"
+              "location": "lacros_version_skew_tests_v111.0.5537.0",
+              "revision": "version:111.0.5537.0"
             }
           ],
           "dimension_sets": [
@@ -86774,9 +86774,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5536.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5537.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 111.0.5536.0",
+        "description": "Run with ash-chrome version 111.0.5537.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -86787,8 +86787,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v111.0.5536.0",
-              "revision": "version:111.0.5536.0"
+              "location": "lacros_version_skew_tests_v111.0.5537.0",
+              "revision": "version:111.0.5537.0"
             }
           ],
           "dimension_sets": [
@@ -86945,9 +86945,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5536.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5537.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 111.0.5536.0",
+        "description": "Run with ash-chrome version 111.0.5537.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -86958,8 +86958,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v111.0.5536.0",
-              "revision": "version:111.0.5536.0"
+              "location": "lacros_version_skew_tests_v111.0.5537.0",
+              "revision": "version:111.0.5537.0"
             }
           ],
           "dimension_sets": [
@@ -87097,9 +87097,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5536.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5537.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 111.0.5536.0",
+        "description": "Run with ash-chrome version 111.0.5537.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -87110,8 +87110,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v111.0.5536.0",
-              "revision": "version:111.0.5536.0"
+              "location": "lacros_version_skew_tests_v111.0.5537.0",
+              "revision": "version:111.0.5537.0"
             }
           ],
           "dimension_sets": [
@@ -87883,9 +87883,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5536.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5537.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 111.0.5536.0",
+        "description": "Run with ash-chrome version 111.0.5537.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -87896,8 +87896,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v111.0.5536.0",
-              "revision": "version:111.0.5536.0"
+              "location": "lacros_version_skew_tests_v111.0.5537.0",
+              "revision": "version:111.0.5537.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index 6935a12..de23fe67 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -18653,12 +18653,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5536.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5537.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 111.0.5536.0",
+        "description": "Run with ash-chrome version 111.0.5537.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -18670,8 +18670,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v111.0.5536.0",
-              "revision": "version:111.0.5536.0"
+              "location": "lacros_version_skew_tests_v111.0.5537.0",
+              "revision": "version:111.0.5537.0"
             }
           ],
           "dimension_sets": [
@@ -18844,12 +18844,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5536.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5537.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 111.0.5536.0",
+        "description": "Run with ash-chrome version 111.0.5537.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -18861,8 +18861,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v111.0.5536.0",
-              "revision": "version:111.0.5536.0"
+              "location": "lacros_version_skew_tests_v111.0.5537.0",
+              "revision": "version:111.0.5537.0"
             }
           ],
           "dimension_sets": [
@@ -19011,12 +19011,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5536.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5537.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 111.0.5536.0",
+        "description": "Run with ash-chrome version 111.0.5537.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -19028,8 +19028,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v111.0.5536.0",
-              "revision": "version:111.0.5536.0"
+              "location": "lacros_version_skew_tests_v111.0.5537.0",
+              "revision": "version:111.0.5537.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/filters/linux.linux-rel-cft.browser_tests.filter b/testing/buildbot/filters/linux.linux-rel-cft.browser_tests.filter
index f3832fe7..3f11f7c 100644
--- a/testing/buildbot/filters/linux.linux-rel-cft.browser_tests.filter
+++ b/testing/buildbot/filters/linux.linux-rel-cft.browser_tests.filter
@@ -38,7 +38,7 @@
 -InteractionTestUtilBrowserTest.CompareScreenshot_WebPage
 -KnownInterceptionDisclosureInfobarTest.CooldownResetsOnBrowserRestartDesktop
 -KnownInterceptionDisclosureInfobarTest.OnlyShowDisclosureOncePerSession
--LayoutInstabilityTest.Sources_Enclosure
+-LayoutInstabilityTest.*
 -MultipleTabSharingUIViewsBrowserTest.CloseTabs
 -MultipleTabSharingUIViewsBrowserTest.StopSharing
 -MultipleTabSharingUIViewsBrowserTest.VerifyUi
diff --git a/testing/buildbot/filters/mac.mac-rel-cft.browser_tests.filter b/testing/buildbot/filters/mac.mac-rel-cft.browser_tests.filter
index c06e3fe..0b3d770 100644
--- a/testing/buildbot/filters/mac.mac-rel-cft.browser_tests.filter
+++ b/testing/buildbot/filters/mac.mac-rel-cft.browser_tests.filter
@@ -38,7 +38,7 @@
 -InteractionTestUtilBrowserTest.CompareScreenshot_WebPage
 -KnownInterceptionDisclosureInfobarTest.CooldownResetsOnBrowserRestartDesktop
 -KnownInterceptionDisclosureInfobarTest.OnlyShowDisclosureOncePerSession
--LayoutInstabilityTest.Sources_Enclosure
+-LayoutInstabilityTest.*
 -MultipleTabSharingUIViewsBrowserTest.CloseTabs
 -MultipleTabSharingUIViewsBrowserTest.StopSharing
 -MultipleTabSharingUIViewsBrowserTest.VerifyUi
diff --git a/testing/buildbot/filters/win.win-rel-cft.browser_tests.filter b/testing/buildbot/filters/win.win-rel-cft.browser_tests.filter
index 2c4bd701..be91943 100644
--- a/testing/buildbot/filters/win.win-rel-cft.browser_tests.filter
+++ b/testing/buildbot/filters/win.win-rel-cft.browser_tests.filter
@@ -38,7 +38,7 @@
 -InteractionTestUtilBrowserTest.CompareScreenshot_WebPage
 -KnownInterceptionDisclosureInfobarTest.CooldownResetsOnBrowserRestartDesktop
 -KnownInterceptionDisclosureInfobarTest.OnlyShowDisclosureOncePerSession
--LayoutInstabilityTest.Sources_Enclosure
+-LayoutInstabilityTest.*
 -MultipleTabSharingUIViewsBrowserTest.CloseTabs
 -MultipleTabSharingUIViewsBrowserTest.StopSharing
 -MultipleTabSharingUIViewsBrowserTest.VerifyUi
diff --git a/testing/buildbot/internal.chromeos.fyi.json b/testing/buildbot/internal.chromeos.fyi.json
index 168df960..a6308b6 100644
--- a/testing/buildbot/internal.chromeos.fyi.json
+++ b/testing/buildbot/internal.chromeos.fyi.json
@@ -1141,7 +1141,7 @@
       {
         "args": [],
         "cros_board": "octopus",
-        "cros_img": "octopus-release/R111-15308.0.0",
+        "cros_img": "octopus-release/R111-15310.0.0",
         "name": "lacros_fyi_tast_tests OCTOPUS_RELEASE_LKGM",
         "swarming": {},
         "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
@@ -1189,7 +1189,7 @@
       {
         "args": [],
         "cros_board": "octopus",
-        "cros_img": "octopus-release/R111-15308.0.0",
+        "cros_img": "octopus-release/R111-15310.0.0",
         "name": "ozone_unittests OCTOPUS_RELEASE_LKGM",
         "swarming": {},
         "test": "ozone_unittests",
@@ -1240,7 +1240,7 @@
       {
         "args": [],
         "cros_board": "hana",
-        "cros_img": "hana-release/R111-15308.0.0",
+        "cros_img": "hana-release/R111-15310.0.0",
         "name": "lacros_all_tast_tests HANA_RELEASE_LKGM",
         "swarming": {},
         "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
@@ -1264,7 +1264,7 @@
       {
         "args": [],
         "cros_board": "hana",
-        "cros_img": "hana-release/R109-15236.35.0",
+        "cros_img": "hana-release/R110-15278.29.0",
         "name": "lacros_all_tast_tests HANA_RELEASE_BETA",
         "swarming": {},
         "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
@@ -1288,7 +1288,7 @@
       {
         "args": [],
         "cros_board": "strongbad",
-        "cros_img": "strongbad-release/R111-15308.0.0",
+        "cros_img": "strongbad-release/R111-15310.0.0",
         "name": "lacros_all_tast_tests STRONGBAD_RELEASE_LKGM",
         "swarming": {},
         "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
@@ -1312,7 +1312,7 @@
       {
         "args": [],
         "cros_board": "strongbad",
-        "cros_img": "strongbad-release/R109-15236.35.0",
+        "cros_img": "strongbad-release/R110-15278.29.0",
         "name": "lacros_all_tast_tests STRONGBAD_RELEASE_BETA",
         "swarming": {},
         "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
@@ -1336,7 +1336,7 @@
       {
         "args": [],
         "cros_board": "hana",
-        "cros_img": "hana-release/R111-15308.0.0",
+        "cros_img": "hana-release/R111-15310.0.0",
         "name": "ozone_unittests HANA_RELEASE_LKGM",
         "swarming": {},
         "test": "ozone_unittests",
@@ -1358,7 +1358,7 @@
       {
         "args": [],
         "cros_board": "hana",
-        "cros_img": "hana-release/R109-15236.35.0",
+        "cros_img": "hana-release/R110-15278.29.0",
         "name": "ozone_unittests HANA_RELEASE_BETA",
         "swarming": {},
         "test": "ozone_unittests",
@@ -1380,7 +1380,7 @@
       {
         "args": [],
         "cros_board": "strongbad",
-        "cros_img": "strongbad-release/R111-15308.0.0",
+        "cros_img": "strongbad-release/R111-15310.0.0",
         "name": "ozone_unittests STRONGBAD_RELEASE_LKGM",
         "swarming": {},
         "test": "ozone_unittests",
@@ -1402,7 +1402,7 @@
       {
         "args": [],
         "cros_board": "strongbad",
-        "cros_img": "strongbad-release/R109-15236.35.0",
+        "cros_img": "strongbad-release/R110-15278.29.0",
         "name": "ozone_unittests STRONGBAD_RELEASE_BETA",
         "swarming": {},
         "test": "ozone_unittests",
@@ -1424,7 +1424,7 @@
       {
         "args": [],
         "cros_board": "hana",
-        "cros_img": "hana-release/R111-15308.0.0",
+        "cros_img": "hana-release/R111-15310.0.0",
         "name": "viz_unittests HANA_RELEASE_LKGM",
         "swarming": {},
         "test": "viz_unittests",
@@ -1446,7 +1446,7 @@
       {
         "args": [],
         "cros_board": "hana",
-        "cros_img": "hana-release/R109-15236.35.0",
+        "cros_img": "hana-release/R110-15278.29.0",
         "name": "viz_unittests HANA_RELEASE_BETA",
         "swarming": {},
         "test": "viz_unittests",
@@ -1468,7 +1468,7 @@
       {
         "args": [],
         "cros_board": "strongbad",
-        "cros_img": "strongbad-release/R111-15308.0.0",
+        "cros_img": "strongbad-release/R111-15310.0.0",
         "name": "viz_unittests STRONGBAD_RELEASE_LKGM",
         "swarming": {},
         "test": "viz_unittests",
@@ -1490,7 +1490,7 @@
       {
         "args": [],
         "cros_board": "strongbad",
-        "cros_img": "strongbad-release/R109-15236.35.0",
+        "cros_img": "strongbad-release/R110-15278.29.0",
         "name": "viz_unittests STRONGBAD_RELEASE_BETA",
         "swarming": {},
         "test": "viz_unittests",
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index ef80663..0cc6d357 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -22,16 +22,16 @@
   },
   'LACROS_VERSION_SKEW_CANARY': {
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5536.0/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v111.0.5537.0/test_ash_chrome',
     ],
-    'description': 'Run with ash-chrome version 111.0.5536.0',
+    'description': 'Run with ash-chrome version 111.0.5537.0',
     'identifier': 'Lacros version skew testing ash canary',
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v111.0.5536.0',
-          'revision': 'version:111.0.5536.0',
+          'location': 'lacros_version_skew_tests_v111.0.5537.0',
+          'revision': 'version:111.0.5537.0',
         },
       ],
     },
@@ -470,8 +470,8 @@
   'CROS_DEDEDE_RELEASE_LKGM': {
     'skylab': {
       'cros_board': 'dedede',
-      'cros_chrome_version': '111.0.5526.0',
-      'cros_img': 'dedede-release/R111-15308.0.0',
+      'cros_chrome_version': '111.0.5530.0',
+      'cros_img': 'dedede-release/R111-15310.0.0',
     },
     'enabled': True,
     'identifier': 'DEDEDE_RELEASE_LKGM',
@@ -488,8 +488,8 @@
   'CROS_DEDEDE_RELEASE_BETA': {
     'skylab': {
       'cros_board': 'dedede',
-      'cros_chrome_version': '109.0.5414.41',
-      'cros_img': 'dedede-release/R109-15236.35.0',
+      'cros_chrome_version': '110.0.5481.32',
+      'cros_img': 'dedede-release/R110-15278.29.0',
     },
     'enabled': True,
     'identifier': 'DEDEDE_RELEASE_BETA',
@@ -506,8 +506,8 @@
   'CROS_EVE_RELEASE_LKGM': {
     'skylab': {
       'cros_board': 'eve',
-      'cros_chrome_version': '111.0.5526.0',
-      'cros_img': 'eve-release/R111-15308.0.0',
+      'cros_chrome_version': '111.0.5530.0',
+      'cros_img': 'eve-release/R111-15310.0.0',
     },
     'enabled': True,
     'identifier': 'EVE_RELEASE_LKGM',
@@ -552,8 +552,8 @@
   'CROS_HANA_RELEASE_LKGM': {
     'skylab': {
       'cros_board': 'hana',
-      'cros_chrome_version': '111.0.5526.0',
-      'cros_img': 'hana-release/R111-15308.0.0',
+      'cros_chrome_version': '111.0.5530.0',
+      'cros_img': 'hana-release/R111-15310.0.0',
     },
     'enabled': True,
     'identifier': 'HANA_RELEASE_LKGM',
@@ -570,8 +570,8 @@
   'CROS_HANA_RELEASE_BETA': {
     'skylab': {
       'cros_board': 'hana',
-      'cros_chrome_version': '109.0.5414.41',
-      'cros_img': 'hana-release/R109-15236.35.0',
+      'cros_chrome_version': '110.0.5481.32',
+      'cros_img': 'hana-release/R110-15278.29.0',
     },
     'enabled': True,
     'identifier': 'HANA_RELEASE_BETA',
@@ -588,8 +588,8 @@
   'CROS_HEROBRINE_RELEASE_LKGM': {
     'skylab': {
       'cros_board': 'herobrine',
-      'cros_chrome_version': '111.0.5526.0',
-      'cros_img': 'herobrine-release/R111-15308.0.0',
+      'cros_chrome_version': '111.0.5530.0',
+      'cros_img': 'herobrine-release/R111-15310.0.0',
     },
     'enabled': True,
     'identifier': 'HEROBRINE_RELEASE_LKGM',
@@ -597,8 +597,8 @@
   'CROS_JACUZZI_RELEASE_LKGM': {
     'skylab': {
       'cros_board': 'jacuzzi',
-      'cros_chrome_version': '111.0.5526.0',
-      'cros_img': 'jacuzzi-release/R111-15308.0.0',
+      'cros_chrome_version': '111.0.5530.0',
+      'cros_img': 'jacuzzi-release/R111-15310.0.0',
     },
     'enabled': True,
     'identifier': 'JACUZZI_RELEASE_LKGM',
@@ -615,8 +615,8 @@
   'CROS_JACUZZI_RELEASE_BETA': {
     'skylab': {
       'cros_board': 'jacuzzi',
-      'cros_chrome_version': '109.0.5414.41',
-      'cros_img': 'jacuzzi-release/R109-15236.35.0',
+      'cros_chrome_version': '110.0.5481.32',
+      'cros_img': 'jacuzzi-release/R110-15278.29.0',
     },
     'enabled': True,
     'identifier': 'JACUZZI_RELEASE_BETA',
@@ -663,8 +663,8 @@
   'CROS_OCTOPUS_RELEASE_LKGM': {
     'skylab': {
       'cros_board': 'octopus',
-      'cros_chrome_version': '111.0.5526.0',
-      'cros_img': 'octopus-release/R111-15308.0.0',
+      'cros_chrome_version': '111.0.5530.0',
+      'cros_img': 'octopus-release/R111-15310.0.0',
     },
     'enabled': True,
     'identifier': 'OCTOPUS_RELEASE_LKGM',
@@ -699,8 +699,8 @@
   'CROS_STRONGBAD_RELEASE_LKGM': {
     'skylab': {
       'cros_board': 'strongbad',
-      'cros_chrome_version': '111.0.5526.0',
-      'cros_img': 'strongbad-release/R111-15308.0.0',
+      'cros_chrome_version': '111.0.5530.0',
+      'cros_img': 'strongbad-release/R111-15310.0.0',
     },
     'enabled': True,
     'identifier': 'STRONGBAD_RELEASE_LKGM',
@@ -717,8 +717,8 @@
   'CROS_STRONGBAD_RELEASE_BETA': {
     'skylab': {
       'cros_board': 'strongbad',
-      'cros_chrome_version': '109.0.5414.41',
-      'cros_img': 'strongbad-release/R109-15236.35.0',
+      'cros_chrome_version': '110.0.5481.32',
+      'cros_img': 'strongbad-release/R110-15278.29.0',
     },
     'enabled': True,
     'identifier': 'STRONGBAD_RELEASE_BETA',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 7c81a47..d5be7cca 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -5691,6 +5691,21 @@
             ]
         }
     ],
+    "IOSForceTranslateEnabled": [
+        {
+            "platforms": [
+                "ios"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "IOSForceTranslateEnabled"
+                    ]
+                }
+            ]
+        }
+    ],
     "IOSGhostCards": [
         {
             "platforms": [
@@ -7819,21 +7834,6 @@
             ]
         }
     ],
-    "OptimizeAccessibilityUiThreadWork": [
-        {
-            "platforms": [
-                "android"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "OptimizeAccessibilityUiThreadWork"
-                    ]
-                }
-            ]
-        }
-    ],
     "OptimizeNetworkBuffers": [
         {
             "platforms": [
diff --git a/third_party/blink/public/mojom/speculation_rules/speculation_rules.mojom b/third_party/blink/public/mojom/speculation_rules/speculation_rules.mojom
index 5acb443..178da5d6 100644
--- a/third_party/blink/public/mojom/speculation_rules/speculation_rules.mojom
+++ b/third_party/blink/public/mojom/speculation_rules/speculation_rules.mojom
@@ -42,7 +42,8 @@
 
 // Shows how eager the developer is to perform the speculation action.
 enum SpeculationEagerness {
-  kDefault,
+  kConservative,
+  kModerate,
   kEager,
 };
 
@@ -71,5 +72,5 @@
 
   // The eagerness level to be used by link selection heuristics to select the
   // candidate.
-  SpeculationEagerness eagerness = kDefault;
+  SpeculationEagerness eagerness = kConservative;
 };
diff --git a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
index d84753a0a..a11cd6d 100644
--- a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
+++ b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
@@ -3320,7 +3320,7 @@
   kCSSCascadeLayers = 4007,
   kCanvasRenderingContext2DConicGradient = 4008,
   kCanvasRenderingContext2DCanvasFilter = 4009,
-  kHTMLParamElementURLParameter = 4010,
+  kOBSOLETE_HTMLParamElementURLParameter = 4010,
   kV8HTMLScriptElement_Supports_Method = 4011,
   kHandwritingRecognitionQueryRecognizer = 4012,
   kV8FileSystemFileHandle_CreateSyncAccessHandle_Method = 4013,
@@ -3426,8 +3426,8 @@
   kWebNfcNdefMakeReadOnly = 4107,
   kV8Navigator_DeprecatedURNToURL_Method = 4108,
   kOBSOLETE_WebAppManifestHandleLinks = 4109,
-  kHTMLParamElementURLParameterInUsePdf = 4110,
-  kHTMLParamElementURLParameterInUseNonPdf = 4111,
+  kOBSOLETE_HTMLParamElementURLParameterInUsePdf = 4110,
+  kOBSOLETE_HTMLParamElementURLParameterInUseNonPdf = 4111,
   kWebTransportServerCertificateHashes = 4112,
   kHiddenAttribute = 4113,
   kHiddenUntilFoundAttribute = 4114,
@@ -3780,6 +3780,9 @@
   kDisableThirdPartySessionStoragePartitioningAfterGeneralPartitioning = 4439,
   kCSSPseudoHasContainsMixOfValidAndInvalid = 4440,
   kCSSPseudoIsWhereContainsMixOfValidAndInvalid = 4441,
+  kPrivateNetworkAccessFetchedSubFrame = 4442,
+  kPrivateNetworkAccessFetchedTopFrame = 4443,
+  kDisableThirdPartyStoragePartitioning = 4444,
 
   // Add new features immediately above this line. Don't change assigned
   // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/public/web/web_element.h b/third_party/blink/public/web/web_element.h
index ee97a96..91e4d36 100644
--- a/third_party/blink/public/web/web_element.h
+++ b/third_party/blink/public/web/web_element.h
@@ -136,10 +136,6 @@
   // /public/web interfaces.
   WebString GetComputedValue(const WebString& property_name);
 
-  // TODO(crbug.com/1286950) Remove this once a decision is made on deprecation
-  // of the <param> URL functionality.
-  void UseCountParamUrlUsageIfNeeded(bool is_pdf) const;
-
 #if INSIDE_BLINK
   WebElement(Element*);
   WebElement& operator=(Element*);
diff --git a/third_party/blink/renderer/core/exported/web_element.cc b/third_party/blink/renderer/core/exported/web_element.cc
index 4289ba9..ae418a4c1 100644
--- a/third_party/blink/renderer/core/exported/web_element.cc
+++ b/third_party/blink/renderer/core/exported/web_element.cc
@@ -237,12 +237,6 @@
   return computed_style->GetPropertyCSSValue(property_id)->CssText();
 }
 
-void WebElement::UseCountParamUrlUsageIfNeeded(bool is_pdf) const {
-  if (auto* object =
-          ::blink::DynamicTo<HTMLObjectElement>(ConstUnwrap<Element>()))
-    object->UseCountParamUrlUsageIfNeeded(is_pdf);
-}
-
 WebElement::WebElement(Element* elem) : WebNode(elem) {}
 
 DEFINE_WEB_NODE_TYPE_CASTS(WebElement, IsElementNode())
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index 30b9efc..15152b3 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -706,8 +706,8 @@
 }
 
 bool LocalFrame::ShouldClose() {
-  // TODO(dcheng): This should be fixed to dispatch beforeunload events to
-  // both local and remote frames.
+  // TODO(crbug.com/1407078): This should be fixed to dispatch beforeunload
+  // events to both local and remote frames.
   return loader_.ShouldClose();
 }
 
diff --git a/third_party/blink/renderer/core/frame/remote_frame.cc b/third_party/blink/renderer/core/frame/remote_frame.cc
index d2a436bd..4647eb6a 100644
--- a/third_party/blink/renderer/core/frame/remote_frame.cc
+++ b/third_party/blink/renderer/core/frame/remote_frame.cc
@@ -387,8 +387,9 @@
 }
 
 bool RemoteFrame::ShouldClose() {
-  // TODO(nasko): Implement running the beforeunload handler in the actual
-  // LocalFrame running in a different process and getting back a real result.
+  // TODO(crbug.com/1407078): Implement running the beforeunload handler in the
+  // actual LocalFrame running in a different process and getting back a real
+  // result.
   return true;
 }
 
diff --git a/third_party/blink/renderer/core/html/forms/resources/list_picker.js b/third_party/blink/renderer/core/html/forms/resources/list_picker.js
index 677c3ba..e487988 100644
--- a/third_party/blink/renderer/core/html/forms/resources/list_picker.js
+++ b/third_party/blink/renderer/core/html/forms/resources/list_picker.js
@@ -471,6 +471,9 @@
       else element.removeAttribute('aria-label');
       element.style.paddingInlineStart = this.config_.paddingStart + 'px';
       if (inGroup) {
+        const extraPaddingForOptionInsideOptgroup = 20;
+        element.style.paddingInlineStart = Number(this.config_.paddingStart) +
+            extraPaddingForOptionInsideOptgroup + 'px';
         element.style.marginInlineStart = (-this.config_.paddingStart) + 'px';
         // Should be synchronized with padding-end in list_picker.css.
         element.style.marginInlineEnd = '-2px';
diff --git a/third_party/blink/renderer/core/html/html_anchor_element.cc b/third_party/blink/renderer/core/html/html_anchor_element.cc
index 5f57a59..6b9ce1b6 100644
--- a/third_party/blink/renderer/core/html/html_anchor_element.cc
+++ b/third_party/blink/renderer/core/html/html_anchor_element.cc
@@ -26,6 +26,7 @@
 
 #include "base/metrics/histogram_macros.h"
 #include "base/time/time.h"
+#include "services/network/public/cpp/features.h"
 #include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/mojom/conversions/attribution_reporting.mojom-blink.h"
 #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
@@ -252,7 +253,12 @@
       // GetDocument().GetFrame() could be null if this method is called from
       // DOMParser::parseFromString(), which internally creates a document
       // and eventually calls this.
-      if (GetDocument().IsDNSPrefetchEnabled() && GetDocument().GetFrame()) {
+      static bool enable =
+          !base::FeatureList::IsEnabled(
+              network::features::kPrefetchDNSWithURL) ||
+          network::features::kPrefetchDNSWithURLAllAnchorElements.Get();
+      if (GetDocument().IsDNSPrefetchEnabled() && GetDocument().GetFrame() &&
+          enable) {
         if (ProtocolIs(parsed_url, "http") || ProtocolIs(parsed_url, "https") ||
             parsed_url.StartsWith("//")) {
           WebPrescientNetworking* web_prescient_networking =
diff --git a/third_party/blink/renderer/core/html/html_object_element.cc b/third_party/blink/renderer/core/html/html_object_element.cc
index 98010b5..c8111c4 100644
--- a/third_party/blink/renderer/core/html/html_object_element.cc
+++ b/third_party/blink/renderer/core/html/html_object_element.cc
@@ -49,8 +49,7 @@
 HTMLObjectElement::HTMLObjectElement(Document& document,
                                      const CreateElementFlags flags)
     : HTMLPlugInElement(html_names::kObjectTag, document, flags),
-      use_fallback_content_(false),
-      should_use_count_param_url_(false) {
+      use_fallback_content_(false) {
   EnsureUserAgentShadowRoot();
 }
 
@@ -122,58 +121,11 @@
   }
 }
 
-// TODO(schenney): crbug.com/572908 This function should not deal with url or
-// serviceType!
 void HTMLObjectElement::ParametersForPlugin(PluginParameters& plugin_params) {
-  HashSet<StringImpl*, CaseFoldingHash> unique_param_names;
-  if (RuntimeEnabledFeatures::HTMLParamElementUrlSupportEnabled()) {
-    // Scan the PARAM children and store their name/value pairs.
-    // Get the URL and type from the params if we don't already have them.
-    // Only scan <param> children if this functionality hasn't been disabled.
-    for (HTMLParamElement* p = Traversal<HTMLParamElement>::FirstChild(*this);
-         p; p = Traversal<HTMLParamElement>::NextSibling(*p)) {
-      String name = p->GetName();
-      if (name.empty())
-        continue;
-
-      unique_param_names.insert(name.Impl());
-      plugin_params.AppendNameWithValue(p->GetName(), p->Value());
-
-      // TODO(schenney): crbug.com/572908 url adjustment does not belong in this
-      // function.
-      // HTML5 says that an object resource's URL is specified by the object's
-      // data attribute, not by a param element with a name of "data". However,
-      // for compatibility, allow the resource's URL to be given by a param
-      // element with one of the common names if we know that resource points
-      // to a plugin.
-      if (url_.empty() && !EqualIgnoringASCIICase(name, "data") &&
-          HTMLParamElement::IsURLParameter(name)) {
-        UseCounter::Count(GetDocument(),
-                          WebFeature::kHTMLParamElementURLParameter);
-        // Use count this <param> usage, if it loads a PDF.
-        should_use_count_param_url_ = true;
-        SetUrl(StripLeadingAndTrailingHTMLSpaces(p->Value()));
-      }
-      // TODO(schenney): crbug.com/572908 serviceType calculation does not
-      // belong in this function.
-      if (service_type_.empty() && EqualIgnoringASCIICase(name, "type")) {
-        wtf_size_t pos = p->Value().Find(";");
-        if (pos != kNotFound)
-          SetServiceType(p->Value().GetString().Left(pos));
-      }
-    }
-  }
-
   // Turn the attributes of the <object> element into arrays, but don't override
   // <param> values.
-  AttributeCollection attributes = Attributes();
-  for (const Attribute& attribute : attributes) {
-    const AtomicString& name = attribute.GetName().LocalName();
-    if (unique_param_names.Contains(name.Impl())) {
-      DCHECK(RuntimeEnabledFeatures::HTMLParamElementUrlSupportEnabled());
-    } else {
-      plugin_params.AppendAttribute(attribute);
-    }
+  for (const Attribute& attribute : Attributes()) {
+    plugin_params.AppendAttribute(attribute);
   }
 
   // Some plugins don't understand the "data" attribute of the OBJECT tag (i.e.
@@ -181,15 +133,6 @@
   plugin_params.MapDataParamToSrc();
 }
 
-void HTMLObjectElement::UseCountParamUrlUsageIfNeeded(bool is_pdf) const {
-  if (should_use_count_param_url_) {
-    UseCounter::Count(
-        GetDocument(),
-        is_pdf ? WebFeature::kHTMLParamElementURLParameterInUsePdf
-               : WebFeature::kHTMLParamElementURLParameterInUseNonPdf);
-  }
-}
-
 bool HTMLObjectElement::HasFallbackContent() const {
   for (Node* child = firstChild(); child; child = child->nextSibling()) {
     // Ignore whitespace-only text, and <param> tags, any other content is
@@ -264,7 +207,6 @@
   PluginParameters plugin_params;
   ParametersForPlugin(plugin_params);
 
-  // Note: url is modified above by parametersForPlugin.
   if (!AllowedToLoadFrameURL(url_)) {
     DispatchErrorEvent();
     return;
diff --git a/third_party/blink/renderer/core/html/html_object_element.h b/third_party/blink/renderer/core/html/html_object_element.h
index 466f324..1dce0e3 100644
--- a/third_party/blink/renderer/core/html/html_object_element.h
+++ b/third_party/blink/renderer/core/html/html_object_element.h
@@ -96,10 +96,6 @@
 
   static bool IsClassOf(const FrameOwner& owner);
 
-  // TODO(crbug.com/1286950) Remove this once a decision is made on deprecation
-  // of the <param> URL functionality.
-  void UseCountParamUrlUsageIfNeeded(bool is_pdf) const;
-
  private:
   void ParseAttribute(const AttributeModificationParams&) override;
   bool IsPresentationAttribute(const QualifiedName&) const override;
@@ -143,10 +139,6 @@
 
   String class_id_;
   bool use_fallback_content_ : 1;
-
-  // TODO(crbug.com/1286950) Remove this once a decision is made on deprecation
-  // of the <param> URL functionality.
-  bool should_use_count_param_url_ : 1;
 };
 
 // Like To<HTMLObjectElement>() but accepts a ListedElement as input
diff --git a/third_party/blink/renderer/core/html/html_param_element.cc b/third_party/blink/renderer/core/html/html_param_element.cc
index 6b1cd4e..6dffb2f 100644
--- a/third_party/blink/renderer/core/html/html_param_element.cc
+++ b/third_party/blink/renderer/core/html/html_param_element.cc
@@ -42,25 +42,4 @@
   return FastGetAttribute(html_names::kValueAttr);
 }
 
-// HTML5 says that an object resource's URL is specified by the object's
-// data attribute, not by a param element. However, for compatibility, also
-// allow the resource's URL to be given by a param of the named "code",
-// "data", "movie", "src" or "url".
-bool HTMLParamElement::IsURLParameter(const String& name) {
-  DCHECK(RuntimeEnabledFeatures::HTMLParamElementUrlSupportEnabled());
-  return EqualIgnoringASCIICase(name, "code") ||
-         EqualIgnoringASCIICase(name, "data") ||
-         EqualIgnoringASCIICase(name, "movie") ||
-         EqualIgnoringASCIICase(name, "src") ||
-         EqualIgnoringASCIICase(name, "url");
-}
-
-bool HTMLParamElement::IsURLAttribute(const Attribute& attribute) const {
-  if (RuntimeEnabledFeatures::HTMLParamElementUrlSupportEnabled() &&
-      attribute.GetName() == html_names::kValueAttr &&
-      IsURLParameter(GetName()))
-    return true;
-  return HTMLElement::IsURLAttribute(attribute);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/html_param_element.h b/third_party/blink/renderer/core/html/html_param_element.h
index d179a90..5e81eee 100644
--- a/third_party/blink/renderer/core/html/html_param_element.h
+++ b/third_party/blink/renderer/core/html/html_param_element.h
@@ -37,9 +37,6 @@
   const AtomicString& Value() const;
 
   static bool IsURLParameter(const String&);
-
- private:
-  bool IsURLAttribute(const Attribute&) const override;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/resources/html.css b/third_party/blink/renderer/core/html/resources/html.css
index a837295..1a91805 100644
--- a/third_party/blink/renderer/core/html/resources/html.css
+++ b/third_party/blink/renderer/core/html/resources/html.css
@@ -927,8 +927,11 @@
     overflow: visible !important;
 }
 
-select:-internal-list-box optgroup option:before {
-    content: "\00a0\00a0\00a0\00a0";;
+/* The padding here should match the value of
+   |extraPaddingForOptionInsideOptgroup| in list_picker.js, which is the
+   padding for select optgroup option. */
+select:-internal-list-box optgroup option {
+    padding-inline-start: 20px;
 }
 
 select:-internal-list-box option,
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc
index f39dd52..594029a 100644
--- a/third_party/blink/renderer/core/layout/layout_object.cc
+++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -4657,6 +4657,10 @@
   NOT_DESTROYED();
   // Should have already set a full paint invalidation reason.
   DCHECK(IsFullPaintInvalidationReason(FullPaintInvalidationReason()));
+  // Subtree full paint invalidation can't be delayed.
+  if (bitfields_.SubtreeShouldDoFullPaintInvalidation()) {
+    return;
+  }
 
   bitfields_.SetShouldDelayFullPaintInvalidation(true);
   if (!ShouldCheckForPaintInvalidation()) {
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h
index 15735c9c..cb33b934 100644
--- a/third_party/blink/renderer/core/layout/layout_object.h
+++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -3175,8 +3175,11 @@
   }
   bool ShouldDoFullPaintInvalidation() const {
     NOT_DESTROYED();
-    if (!ShouldDelayFullPaintInvalidation() &&
-        FullPaintInvalidationReason() != PaintInvalidationReason::kNone) {
+    if (ShouldDelayFullPaintInvalidation()) {
+      DCHECK(!bitfields_.SubtreeShouldDoFullPaintInvalidation());
+      return false;
+    }
+    if (FullPaintInvalidationReason() != PaintInvalidationReason::kNone) {
       DCHECK(IsFullPaintInvalidationReason(FullPaintInvalidationReason()));
       DCHECK(ShouldCheckForPaintInvalidation());
       return true;
diff --git a/third_party/blink/renderer/core/layout/layout_object_test.cc b/third_party/blink/renderer/core/layout/layout_object_test.cc
index 621296c4..24f9946f 100644
--- a/third_party/blink/renderer/core/layout/layout_object_test.cc
+++ b/third_party/blink/renderer/core/layout/layout_object_test.cc
@@ -603,6 +603,49 @@
   EXPECT_FALSE(object->DescendantNeedsPaintPropertyUpdate());
 }
 
+TEST_F(LayoutObjectTest, DelayFullPaintInvalidation) {
+  LayoutObject* object = GetDocument().body()->GetLayoutObject();
+  object->SetShouldDoFullPaintInvalidation();
+  object->SetShouldDelayFullPaintInvalidation();
+  EXPECT_FALSE(object->ShouldDoFullPaintInvalidation());
+  EXPECT_TRUE(object->ShouldDelayFullPaintInvalidation());
+
+  UpdateAllLifecyclePhasesForTest();
+  EXPECT_FALSE(object->ShouldDoFullPaintInvalidation());
+  // ShouldDelayFullPaintInvalidation is not preserved.
+  EXPECT_TRUE(object->ShouldDelayFullPaintInvalidation());
+
+  object->SetShouldDoFullPaintInvalidation();
+  EXPECT_TRUE(object->ShouldDoFullPaintInvalidation());
+  // ShouldDelayFullPaintInvalidation is reset by
+  // SetShouldDoFullPaintInvalidation().
+  EXPECT_FALSE(object->ShouldDelayFullPaintInvalidation());
+
+  UpdateAllLifecyclePhasesForTest();
+  EXPECT_FALSE(object->ShouldDoFullPaintInvalidation());
+  EXPECT_FALSE(object->ShouldDelayFullPaintInvalidation());
+}
+
+TEST_F(LayoutObjectTest, SubtreeAndDelayFullPaintInvalidation) {
+  LayoutObject* object = GetDocument().body()->GetLayoutObject();
+  object->SetShouldDoFullPaintInvalidation();
+  object->SetShouldDelayFullPaintInvalidation();
+  object->SetSubtreeShouldDoFullPaintInvalidation();
+  EXPECT_TRUE(object->SubtreeShouldDoFullPaintInvalidation());
+  EXPECT_TRUE(object->ShouldDoFullPaintInvalidation());
+  EXPECT_FALSE(object->ShouldDelayFullPaintInvalidation());
+
+  object->SetShouldDelayFullPaintInvalidation();
+  EXPECT_TRUE(object->SubtreeShouldDoFullPaintInvalidation());
+  EXPECT_TRUE(object->ShouldDoFullPaintInvalidation());
+  EXPECT_FALSE(object->ShouldDelayFullPaintInvalidation());
+
+  UpdateAllLifecyclePhasesForTest();
+  EXPECT_FALSE(object->SubtreeShouldDoFullPaintInvalidation());
+  EXPECT_FALSE(object->ShouldDoFullPaintInvalidation());
+  EXPECT_FALSE(object->ShouldDelayFullPaintInvalidation());
+}
+
 TEST_F(LayoutObjectTest, SubtreePaintPropertyUpdateReasons) {
   LayoutObject* object = GetDocument().body()->GetLayoutObject();
   object->AddSubtreePaintPropertyUpdateReason(
diff --git a/third_party/blink/renderer/core/paint/box_border_painter.cc b/third_party/blink/renderer/core/paint/box_border_painter.cc
index e1311bb..286cd88 100644
--- a/third_party/blink/renderer/core/paint/box_border_painter.cc
+++ b/third_party/blink/renderer/core/paint/box_border_painter.cc
@@ -1429,12 +1429,8 @@
       return;
     }
     case EBorderStyle::kInset:
-      if (side == BoxSide::kTop || side == BoxSide::kLeft)
-        color = color.Dark();
-      break;
     case EBorderStyle::kOutset:
-      if (side == BoxSide::kBottom || side == BoxSide::kRight)
-        color = color.Dark();
+      color = CalculateBorderStyleColor(border_style, side, color);
       break;
     default:
       break;
diff --git a/third_party/blink/renderer/core/speculation_rules/document_rule_predicate.cc b/third_party/blink/renderer/core/speculation_rules/document_rule_predicate.cc
index e90b5de..68e4c2ee 100644
--- a/third_party/blink/renderer/core/speculation_rules/document_rule_predicate.cc
+++ b/third_party/blink/renderer/core/speculation_rules/document_rule_predicate.cc
@@ -7,6 +7,8 @@
 #include "base/containers/contains.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_union_urlpatterninit_usvstring.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_url_pattern_init.h"
+#include "third_party/blink/renderer/core/css/parser/css_parser.h"
+#include "third_party/blink/renderer/core/css/style_rule.h"
 #include "third_party/blink/renderer/core/dom/element.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/html/html_anchor_element.h"
@@ -193,6 +195,49 @@
   HeapVector<Member<URLPattern>> patterns_;
 };
 
+// Represents a document rule CSS selector predicate:
+// https://wicg.github.io/nav-speculation/speculation-rules.html#document-rule-css-selector-predicate
+class CSSSelectorPredicate : public DocumentRulePredicate {
+ public:
+  explicit CSSSelectorPredicate(HeapVector<Member<StyleRule>> style_rules)
+      : style_rules_(std::move(style_rules)) {}
+
+  bool Matches(const HTMLAnchorElement& link) const override {
+    // TODO(crbug.com/1371522): Implement this.
+    return false;
+  }
+
+  String ToString() const override {
+    StringBuilder builder;
+    builder.Append("Selector([");
+    for (wtf_size_t i = 0; i < style_rules_.size(); i++) {
+      builder.Append(style_rules_[i]->SelectorsText());
+      if (i != style_rules_.size() - 1) {
+        builder.Append(", ");
+      }
+    }
+    builder.Append("])");
+    return builder.ReleaseString();
+  }
+
+  Type GetTypeForTesting() const override { return Type::kCSSSelectors; }
+
+  HeapVector<Member<StyleRule>> GetStyleRulesForTesting() const override {
+    return style_rules_;
+  }
+
+  void Trace(Visitor* visitor) const override {
+    visitor->Trace(style_rules_);
+    DocumentRulePredicate::Trace(visitor);
+  }
+
+ private:
+  // TODO(crbug.com/1371522): If we do not end up integrating with the
+  // style engine, change this to use CSSSelectorList instead of StyleRule to
+  // save space.
+  HeapVector<Member<StyleRule>> style_rules_;
+};
+
 namespace {
 URLPattern* ParseRawPattern(JSONValue* raw_pattern,
                             const KURL& base_url,
@@ -416,8 +461,51 @@
 
   // If predicateType is "selector_matches"
   if (predicate_type == "selector_matches" && input->size() == 1) {
-    // TODO(crbug.com/1371522): Implement this.
-    NOTIMPLEMENTED();
+    const bool selector_matches_enabled = RuntimeEnabledFeatures::
+        SpeculationRulesDocumentRulesSelectorMatchesEnabled(execution_context);
+    if (!selector_matches_enabled) {
+      return nullptr;
+    }
+
+    // Let rawSelectors be input["selector_matches"].
+    Vector<JSONValue*> raw_selectors;
+    JSONArray* selector_matches = input->GetArray("selector_matches");
+    if (selector_matches) {
+      for (wtf_size_t i = 0; i < selector_matches->size(); i++) {
+        raw_selectors.push_back(selector_matches->at(i));
+      }
+    } else {
+      // If rawSelectors is not a list, then set rawSelectors to « rawSelectors
+      // ».
+      raw_selectors.push_back(input->Get("selector_matches"));
+    }
+    // Let selectors be an empty list.
+    HeapVector<Member<StyleRule>> selectors;
+    HeapVector<CSSSelector> arena;
+    CSSPropertyValueSet* empty_properties =
+        ImmutableCSSPropertyValueSet::Create(nullptr, 0, kUASheetMode);
+    CSSParserContext* css_parser_context =
+        MakeGarbageCollected<CSSParserContext>(*execution_context);
+    for (auto* raw_selector : raw_selectors) {
+      String raw_selector_string;
+      // If rawSelector is not a string, then return null.
+      if (!raw_selector->AsString(&raw_selector_string)) {
+        return nullptr;
+      }
+
+      // Parse a selector from rawSelector. If the result is failure, then
+      // return null. Otherwise, let selector be the result.
+      base::span<CSSSelector> selector_vector = CSSParser::ParseSelector(
+          css_parser_context, nullptr, nullptr, raw_selector_string, arena);
+      if (selector_vector.empty()) {
+        return nullptr;
+      }
+      StyleRule* selector =
+          StyleRule::Create(selector_vector, empty_properties);
+      // Append selector to selectors.
+      selectors.push_back(std::move(selector));
+    }
+    return MakeGarbageCollected<CSSSelectorPredicate>(std::move(selectors));
   }
 
   return nullptr;
@@ -441,6 +529,12 @@
   return {};
 }
 
+HeapVector<Member<StyleRule>> DocumentRulePredicate::GetStyleRulesForTesting()
+    const {
+  NOTREACHED();
+  return {};
+}
+
 void DocumentRulePredicate::Trace(Visitor*) const {}
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/speculation_rules/document_rule_predicate.h b/third_party/blink/renderer/core/speculation_rules/document_rule_predicate.h
index 39749f8..12508d8 100644
--- a/third_party/blink/renderer/core/speculation_rules/document_rule_predicate.h
+++ b/third_party/blink/renderer/core/speculation_rules/document_rule_predicate.h
@@ -18,6 +18,7 @@
 class ExecutionContext;
 class JSONObject;
 class KURL;
+class StyleRule;
 class URLPattern;
 
 class CORE_EXPORT DocumentRulePredicate
@@ -37,12 +38,13 @@
   virtual bool Matches(const HTMLAnchorElement& link) const = 0;
 
   // Methods for testing.
-  enum class Type { kAnd, kOr, kNot, kURLPatterns };
+  enum class Type { kAnd, kOr, kNot, kURLPatterns, kCSSSelectors };
   virtual String ToString() const = 0;
   virtual Type GetTypeForTesting() const = 0;
   virtual HeapVector<Member<DocumentRulePredicate>> GetSubPredicatesForTesting()
       const;
   virtual HeapVector<Member<URLPattern>> GetURLPatternsForTesting() const;
+  virtual HeapVector<Member<StyleRule>> GetStyleRulesForTesting() const;
 
   virtual void Trace(Visitor*) const;
 };
diff --git a/third_party/blink/renderer/core/speculation_rules/document_speculation_rules.cc b/third_party/blink/renderer/core/speculation_rules/document_speculation_rules.cc
index cce4d4f..2a4e02d6 100644
--- a/third_party/blink/renderer/core/speculation_rules/document_speculation_rules.cc
+++ b/third_party/blink/renderer/core/speculation_rules/document_speculation_rules.cc
@@ -346,10 +346,11 @@
             rule->requires_anonymous_client_ip_when_cross_origin(),
             rule->target_browsing_context_name_hint().value_or(
                 mojom::blink::SpeculationTargetHint::kNoHint),
-            mojom::blink::SpeculationEagerness::
-                kEager));  // The default Eagerness value for |"source": "list"|
-                           // rules is |kEager|. More info can be found here:
-                           // https://docs.google.com/document/d/1nKOUX6R9seR5e7nyR16mj0lp3C1z7Qox-_KUt4C9E2U
+            // The default Eagerness value for |"source": "list"| rules is
+            // |kEager|. More info can be found here:
+            // https://github.com/WICG/nav-speculation/blob/main/triggers.md#eagerness
+            rule->eagerness().value_or(
+                mojom::blink::SpeculationEagerness::kEager)));
       }
     }
   };
@@ -436,11 +437,11 @@
                     rule->requires_anonymous_client_ip_when_cross_origin(),
                     rule->target_browsing_context_name_hint().value_or(
                         mojom::blink::SpeculationTargetHint::kNoHint),
-                    mojom::blink::SpeculationEagerness::
-                        kDefault);  // The default Eagerness value for
-                                    // |"source": "document"| rules is
-                                    // |kDefault|. More info can be found here:
-                                    // https://docs.google.com/document/d/1nKOUX6R9seR5e7nyR16mj0lp3C1z7Qox-_KUt4C9E2U
+                    // The default Eagerness value for |"source": "document"|
+                    // rules is |kConservative|. More info can be found here:
+                    // https://github.com/WICG/nav-speculation/blob/main/triggers.md#eagerness
+                    rule->eagerness().value_or(
+                        mojom::blink::SpeculationEagerness::kConservative));
             link_candidates.push_back(std::move(candidate));
           }
         };
diff --git a/third_party/blink/renderer/core/speculation_rules/speculation_rule.cc b/third_party/blink/renderer/core/speculation_rules/speculation_rule.cc
index d87be47..a9c8583f 100644
--- a/third_party/blink/renderer/core/speculation_rules/speculation_rule.cc
+++ b/third_party/blink/renderer/core/speculation_rules/speculation_rule.cc
@@ -14,12 +14,14 @@
     DocumentRulePredicate* predicate,
     RequiresAnonymousClientIPWhenCrossOrigin requires_anonymous_client_ip,
     absl::optional<mojom::blink::SpeculationTargetHint> target_hint,
-    absl::optional<network::mojom::ReferrerPolicy> referrer_policy)
+    absl::optional<network::mojom::ReferrerPolicy> referrer_policy,
+    absl::optional<mojom::blink::SpeculationEagerness> eagerness)
     : urls_(std::move(urls)),
       predicate_(predicate),
       requires_anonymous_client_ip_(requires_anonymous_client_ip),
       target_browsing_context_name_hint_(target_hint),
-      referrer_policy_(referrer_policy) {}
+      referrer_policy_(referrer_policy),
+      eagerness_(eagerness) {}
 
 SpeculationRule::~SpeculationRule() = default;
 
diff --git a/third_party/blink/renderer/core/speculation_rules/speculation_rule.h b/third_party/blink/renderer/core/speculation_rules/speculation_rule.h
index 702e77f2..e251b451f 100644
--- a/third_party/blink/renderer/core/speculation_rules/speculation_rule.h
+++ b/third_party/blink/renderer/core/speculation_rules/speculation_rule.h
@@ -33,7 +33,8 @@
       DocumentRulePredicate*,
       RequiresAnonymousClientIPWhenCrossOrigin,
       absl::optional<mojom::blink::SpeculationTargetHint> target_hint,
-      absl::optional<network::mojom::ReferrerPolicy>);
+      absl::optional<network::mojom::ReferrerPolicy>,
+      absl::optional<mojom::blink::SpeculationEagerness>);
   ~SpeculationRule();
 
   const Vector<KURL>& urls() const { return urls_; }
@@ -48,6 +49,9 @@
   absl::optional<network::mojom::ReferrerPolicy> referrer_policy() const {
     return referrer_policy_;
   }
+  absl::optional<mojom::blink::SpeculationEagerness> eagerness() const {
+    return eagerness_;
+  }
 
   void Trace(Visitor*) const;
 
@@ -58,6 +62,7 @@
   const absl::optional<mojom::blink::SpeculationTargetHint>
       target_browsing_context_name_hint_;
   const absl::optional<network::mojom::ReferrerPolicy> referrer_policy_;
+  absl::optional<mojom::blink::SpeculationEagerness> eagerness_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/speculation_rules/speculation_rule_set.cc b/third_party/blink/renderer/core/speculation_rules/speculation_rule_set.cc
index 521f883e..6b4d5ff 100644
--- a/third_party/blink/renderer/core/speculation_rules/speculation_rule_set.cc
+++ b/third_party/blink/renderer/core/speculation_rules/speculation_rule_set.cc
@@ -59,14 +59,24 @@
   // and "relative_to", then return null.
   const char* const kKnownKeys[] = {"source",      "urls",  "requires",
                                     "target_hint", "where", "relative_to"};
+  const auto kConditionalKnownKeys = [context]() {
+    Vector<const char*, 4> conditional_known_keys;
+    if (RuntimeEnabledFeatures::SpeculationRulesReferrerPolicyKeyEnabled(
+            context)) {
+      conditional_known_keys.push_back("referrer_policy");
+    }
+    if (RuntimeEnabledFeatures::SpeculationRulesEagernessEnabled(context)) {
+      conditional_known_keys.push_back("eagerness");
+    }
+    return conditional_known_keys;
+  }();
+
   for (wtf_size_t i = 0; i < input->size(); ++i) {
     const String& input_key = input->at(i).first;
-    const bool conditionally_known_key =
-        RuntimeEnabledFeatures::SpeculationRulesReferrerPolicyKeyEnabled(
-            context) &&
-        input_key == "referrer_policy";
-    if (!base::Contains(kKnownKeys, input_key) && !conditionally_known_key)
+    if (!base::Contains(kKnownKeys, input_key) &&
+        !base::Contains(kConditionalKnownKeys, input_key)) {
       return nullptr;
+    }
   }
 
   bool document_rules_enabled =
@@ -232,9 +242,30 @@
     }
   }
 
+  absl::optional<mojom::blink::SpeculationEagerness> eagerness;
+  if (JSONValue* eagerness_value = input->Get("eagerness")) {
+    // Feature gated due to known keys check above.
+    DCHECK(RuntimeEnabledFeatures::SpeculationRulesEagernessEnabled(context));
+
+    String eagerness_str;
+    if (!eagerness_value->AsString(&eagerness_str)) {
+      return nullptr;
+    }
+
+    if (eagerness_str == "eager") {
+      eagerness = mojom::blink::SpeculationEagerness::kEager;
+    } else if (eagerness_str == "moderate") {
+      eagerness = mojom::blink::SpeculationEagerness::kModerate;
+    } else if (eagerness_str == "conservative") {
+      eagerness = mojom::blink::SpeculationEagerness::kConservative;
+    } else {
+      return nullptr;
+    }
+  }
+
   return MakeGarbageCollected<SpeculationRule>(
       std::move(urls), document_rule_predicate, requires_anonymous_client_ip,
-      target_hint, referrer_policy);
+      target_hint, referrer_policy, eagerness);
 }
 
 }  // namespace
diff --git a/third_party/blink/renderer/core/speculation_rules/speculation_rule_set_test.cc b/third_party/blink/renderer/core/speculation_rules/speculation_rule_set_test.cc
index 788ff39..5033426 100644
--- a/third_party/blink/renderer/core/speculation_rules/speculation_rule_set_test.cc
+++ b/third_party/blink/renderer/core/speculation_rules/speculation_rule_set_test.cc
@@ -14,6 +14,7 @@
 #include "third_party/blink/public/mojom/speculation_rules/speculation_rules.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_union_urlpatterninit_usvstring.h"
+#include "third_party/blink/renderer/core/css/style_rule.h"
 #include "third_party/blink/renderer/core/dom/shadow_root.h"
 #include "third_party/blink/renderer/core/execution_context/agent.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
@@ -928,110 +929,46 @@
       return "Not";
     case DocumentRulePredicate::Type::kURLPatterns:
       return "Href";
+    case DocumentRulePredicate::Type::kCSSSelectors:
+      return "Selector";
   }
 }
 
-std::string GetMatcherDescription(
-    const ::testing::Matcher<DocumentRulePredicate>& matcher) {
-  std::stringstream ss;
-  matcher.DescribeTo(&ss);
-  return ss.str();
-}
-
-class ConditionMatcher {
+template <typename ItemType>
+class PredicateMatcher {
  public:
-  explicit ConditionMatcher(
-      DocumentRulePredicate::Type type,
-      Vector<::testing::Matcher<DocumentRulePredicate>> matchers)
-      : type_(type), matchers_(std::move(matchers)) {}
+  using DocumentRulePredicateGetter =
+      HeapVector<Member<ItemType>> (DocumentRulePredicate::*)() const;
+
+  explicit PredicateMatcher(Vector<::testing::Matcher<ItemType>> matchers,
+                            DocumentRulePredicate::Type type,
+                            DocumentRulePredicateGetter getter)
+      : matchers_(std::move(matchers)), type_(type), getter_(getter) {}
 
   bool MatchAndExplain(DocumentRulePredicate* predicate,
                        ::testing::MatchResultListener* listener) const {
-    if (!predicate)
+    if (!predicate) {
       return false;
+    }
     return MatchAndExplain(*predicate, listener);
   }
 
   bool MatchAndExplain(const DocumentRulePredicate& predicate,
                        ::testing::MatchResultListener* listener) const {
-    ::testing::StringMatchResultListener inner_listener;
-    const auto& predicates = predicate.GetSubPredicatesForTesting();
-    if (predicate.GetTypeForTesting() != type_ ||
-        predicates.size() != matchers_.size()) {
+    if (predicate.GetTypeForTesting() != type_) {
       *listener << predicate.ToString();
       return false;
     }
 
-    bool matches = true;
-    for (wtf_size_t i = 0; i < matchers_.size(); i++) {
-      if (!matchers_[i].MatchAndExplain(*(predicates[i]), &inner_listener)) {
-        matches = false;
-        break;
-      }
-    }
-    *listener << predicate.ToString();
-    return matches;
-  }
-
-  void DescribeTo(::std::ostream* os) const {
-    *os << GetTypeString(type_) << "(";
-    for (wtf_size_t i = 0; i < matchers_.size(); i++) {
-      *os << GetMatcherDescription(matchers_[i]);
-      if (i != matchers_.size() - 1)
-        *os << ", ";
-    }
-    *os << ")";
-  }
-
-  void DescribeNegationTo(::std::ostream* os) const { DescribeTo(os); }
-
- private:
-  DocumentRulePredicate::Type type_;
-  Vector<::testing::Matcher<DocumentRulePredicate>> matchers_;
-};
-
-auto And(Vector<::testing::Matcher<DocumentRulePredicate>> matchers = {}) {
-  return testing::MakePolymorphicMatcher(
-      ConditionMatcher(DocumentRulePredicate::Type::kAnd, std::move(matchers)));
-}
-
-auto Or(Vector<::testing::Matcher<DocumentRulePredicate>> matchers = {}) {
-  return testing::MakePolymorphicMatcher(
-      ConditionMatcher(DocumentRulePredicate::Type::kOr, std::move(matchers)));
-}
-
-auto Neg(::testing::Matcher<DocumentRulePredicate> matcher) {
-  return testing::MakePolymorphicMatcher(
-      ConditionMatcher(DocumentRulePredicate::Type::kNot, {matcher}));
-}
-
-class HrefMatcher {
- public:
-  explicit HrefMatcher(Vector<::testing::Matcher<URLPattern>> pattern_matchers)
-      : pattern_matchers_(std::move(pattern_matchers)) {}
-
-  bool MatchAndExplain(DocumentRulePredicate* predicate,
-                       ::testing::MatchResultListener* listener) const {
-    if (!predicate)
-      return false;
-    return MatchAndExplain(*predicate, listener);
-  }
-
-  bool MatchAndExplain(const DocumentRulePredicate& predicate,
-                       ::testing::MatchResultListener* listener) const {
-    if (predicate.GetTypeForTesting() !=
-            DocumentRulePredicate::Type::kURLPatterns ||
-        predicate.GetURLPatternsForTesting().size() !=
-            pattern_matchers_.size()) {
+    HeapVector<Member<ItemType>> items = ((predicate).*(getter_))();
+    if (items.size() != matchers_.size()) {
       *listener << predicate.ToString();
       return false;
     }
 
-    auto patterns = predicate.GetURLPatternsForTesting();
     ::testing::StringMatchResultListener inner_listener;
-    for (wtf_size_t i = 0; i < pattern_matchers_.size(); i++) {
-      if (!pattern_matchers_[i].MatchAndExplain(*patterns[i],
-                                                &inner_listener)) {
+    for (wtf_size_t i = 0; i < matchers_.size(); i++) {
+      if (!matchers_[i].MatchAndExplain(*items[i], &inner_listener)) {
         *listener << predicate.ToString();
         return false;
       }
@@ -1040,11 +977,12 @@
   }
 
   void DescribeTo(::std::ostream* os) const {
-    *os << GetTypeString(DocumentRulePredicate::Type::kURLPatterns) << "([";
-    for (wtf_size_t i = 0; i < pattern_matchers_.size(); i++) {
-      pattern_matchers_[i].DescribeTo(os);
-      if (i != pattern_matchers_.size() - 1)
+    *os << GetTypeString(type_) << "([";
+    for (wtf_size_t i = 0; i < matchers_.size(); i++) {
+      matchers_[i].DescribeTo(os);
+      if (i != matchers_.size() - 1) {
         *os << ", ";
+      }
     }
     *os << "])";
   }
@@ -1052,11 +990,52 @@
   void DescribeNegationTo(::std::ostream* os) const { DescribeTo(os); }
 
  private:
-  Vector<::testing::Matcher<URLPattern>> pattern_matchers_;
+  Vector<::testing::Matcher<ItemType>> matchers_;
+  DocumentRulePredicate::Type type_;
+  DocumentRulePredicateGetter getter_;
 };
 
+template <typename ItemType>
+auto MakePredicateMatcher(
+    Vector<::testing::Matcher<ItemType>> matchers,
+    DocumentRulePredicate::Type type,
+    typename PredicateMatcher<ItemType>::DocumentRulePredicateGetter getter) {
+  return testing::MakePolymorphicMatcher(
+      PredicateMatcher<ItemType>(std::move(matchers), type, getter));
+}
+
+auto MakeConditionMatcher(
+    Vector<::testing::Matcher<DocumentRulePredicate>> matchers,
+    DocumentRulePredicate::Type type) {
+  return MakePredicateMatcher(
+      std::move(matchers), type,
+      &DocumentRulePredicate::GetSubPredicatesForTesting);
+}
+
+auto And(Vector<::testing::Matcher<DocumentRulePredicate>> matchers = {}) {
+  return MakeConditionMatcher(std::move(matchers),
+                              DocumentRulePredicate::Type::kAnd);
+}
+
+auto Or(Vector<::testing::Matcher<DocumentRulePredicate>> matchers = {}) {
+  return MakeConditionMatcher(std::move(matchers),
+                              DocumentRulePredicate::Type::kOr);
+}
+
+auto Neg(::testing::Matcher<DocumentRulePredicate> matcher) {
+  return MakeConditionMatcher({matcher}, DocumentRulePredicate::Type::kNot);
+}
+
 auto Href(Vector<::testing::Matcher<URLPattern>> pattern_matchers = {}) {
-  return testing::MakePolymorphicMatcher(HrefMatcher(pattern_matchers));
+  return MakePredicateMatcher(std::move(pattern_matchers),
+                              DocumentRulePredicate::Type::kURLPatterns,
+                              &DocumentRulePredicate::GetURLPatternsForTesting);
+}
+
+auto Selector(Vector<::testing::Matcher<StyleRule>> style_rule_matchers = {}) {
+  return MakePredicateMatcher(std::move(style_rule_matchers),
+                              DocumentRulePredicate::Type::kCSSSelectors,
+                              &DocumentRulePredicate::GetStyleRulesForTesting);
 }
 
 class URLPatternMatcher {
@@ -1104,6 +1083,36 @@
       URLPatternMatcher(pattern, base_url));
 }
 
+class StyleRuleMatcher {
+ public:
+  explicit StyleRuleMatcher(String selector_text)
+      : selector_text_(std::move(selector_text)) {}
+
+  bool MatchAndExplain(StyleRule* style_rule,
+                       ::testing::MatchResultListener* listener) const {
+    if (!style_rule) {
+      return false;
+    }
+    return MatchAndExplain(*style_rule, listener);
+  }
+
+  bool MatchAndExplain(const StyleRule& style_rule,
+                       ::testing::MatchResultListener* listener) const {
+    return style_rule.SelectorsText() == selector_text_;
+  }
+
+  void DescribeTo(::std::ostream* os) const { *os << selector_text_; }
+
+  void DescribeNegationTo(::std::ostream* os) const { DescribeTo(os); }
+
+ private:
+  String selector_text_;
+};
+
+auto StyleRuleWithSelectorText(String selector_text) {
+  return ::testing::MakePolymorphicMatcher(StyleRuleMatcher(selector_text));
+}
+
 class DocumentRulesTest : public SpeculationRuleSetTest {
  public:
   ~DocumentRulesTest() override = default;
@@ -1291,6 +1300,8 @@
 }
 
 TEST_F(DocumentRulesTest, DropInvalidRules) {
+  ScopedSpeculationRulesDocumentRulesSelectorMatchesForTest
+      enabled_selector_matches_{true};
   auto* rule_set = CreateRuleSet(
       R"({"prefetch": [)"
 
@@ -1380,18 +1391,46 @@
                    "relative_to": "document",
                    "world-cup": "2022"}},)"
 
+      // "selector_matches" paired with another key.
+      R"({"source": "document",
+          "where": {"selector_matches": ".valid", "second": "value"}
+        },)"
+
+      // "selector_matches" with an object value.
+      R"({"source": "document",
+          "where": {"selector_matches": {"selector": ".valid"}}
+        },)"
+
+      // "selector_matches" with an invalid CSS selector.
+      R"({"source": "document",
+          "where": {"selector_matches": "#invalid#"}
+        },)"
+
+      // "selector_matches" with a list with an object.
+      R"({"source": "document",
+          "where": {"selector_matches": [{"selector": ".valid"}]}
+        },)"
+
+      // "selector_matches" with a list with one valid and one invalid CSS
+      // selector.
+      R"({"source": "document",
+        "where": {"selector_matches": [".valid", "#invalid#"]}
+        },)"
+
       // valid document rule.
       R"({"source": "document",
-          "where": {"and": [
-            {"or": [{"href_matches": "/hello.html"}]},
-            {"not": {"and": [{"href_matches": {"hostname": "world.com"}}]}}
-          ]}
-         }]})",
+        "where": {"and": [
+          {"or": [{"href_matches": "/hello.html"},
+                  {"selector_matches": ".valid"}]},
+          {"not": {"and": [{"href_matches": {"hostname": "world.com"}}]}}
+        ]}
+    }]})",
       KURL("https://example.com/"), execution_context());
   ASSERT_TRUE(rule_set);
   EXPECT_THAT(rule_set->prefetch_rules(),
               ElementsAre(MatchesPredicate(
-                  And({Or({Href({URLPattern("/hello.html")})}),
+                  And({Or({Href({URLPattern("/hello.html")}),
+                           Selector({StyleRuleWithSelectorText(".valid")})}),
                        Neg(And({Href({URLPattern("https://world.com")})}))}))));
 }
 
@@ -1501,6 +1540,13 @@
       ::testing::UnorderedElementsAre(urls...));
 }
 
+// Matches a SpeculationCandidatePtr with an Eagerness.
+auto HasEagerness(
+    ::testing::Matcher<blink::mojom::SpeculationEagerness> matcher) {
+  return ::testing::Pointee(::testing::Field(
+      "eagerness", &mojom::blink::SpeculationCandidate::eagerness, matcher));
+}
+
 // Matches a SpeculationCandidatePtr with a KURL.
 auto HasURL(::testing::Matcher<KURL> matcher) {
   return ::testing::Pointee(::testing::Field(
@@ -2124,5 +2170,236 @@
   EXPECT_THAT(candidates, HasURLs("https://bar.com/bart"));
 }
 
+// Tests that "selector_matches" is not parsed without the RuntimeEnabledFeature
+// enabled.
+TEST_F(DocumentRulesTest, SelectorMatchesIsNotParsed) {
+  auto* rule_set =
+      CreateRuleSet(R"({"prefetch": [
+    {"source": "document", "where": {"selector_matches": ".valid"}}
+  ]})",
+                    KURL("https://example.com"), execution_context());
+  EXPECT_TRUE(rule_set->prefetch_rules().empty());
+}
+
+TEST_F(DocumentRulesTest, ParseSelectorMatches) {
+  ScopedSpeculationRulesDocumentRulesSelectorMatchesForTest
+      enabled_selector_matches_{true};
+  auto* simple_selector_matches = CreatePredicate(R"(
+    "selector_matches": ".valid"
+  )");
+  EXPECT_THAT(simple_selector_matches,
+              Selector({StyleRuleWithSelectorText(".valid")}));
+
+  auto* simple_selector_matches_list = CreatePredicate(R"(
+    "selector_matches": [".one", "#two"]
+  )");
+  EXPECT_THAT(simple_selector_matches_list,
+              Selector({StyleRuleWithSelectorText(".one"),
+                        StyleRuleWithSelectorText("#two")}));
+
+  auto* selector_matches_with_compound_selector = CreatePredicate(R"(
+    "selector_matches": ".interesting-section > a"
+  )");
+  EXPECT_THAT(
+      selector_matches_with_compound_selector,
+      Selector({StyleRuleWithSelectorText(".interesting-section > a")}));
+}
+
+TEST_F(SpeculationRuleSetTest, EagernessRuntimeEnabledFlag) {
+  ScopedSpeculationRulesEagernessForTest enable_eagerness{false};
+
+  DummyPageHolder page_holder;
+  StubSpeculationHost speculation_host;
+
+  String speculation_script = R"({
+        "prefetch": [
+          {
+            "source": "list",
+            "urls": ["https://example.com/prefetch/list/page1.html"],
+            "eagerness": "conservative"
+          }
+        ]
+      })";
+  PropagateRulesToStubSpeculationHost(page_holder, speculation_host,
+                                      speculation_script);
+  const auto& candidates = speculation_host.candidates();
+  EXPECT_TRUE(candidates.empty());
+}
+
+TEST_F(SpeculationRuleSetTest, Eagerness) {
+  ScopedSpeculationRulesEagernessForTest enable_eagerness{true};
+  ScopedSpeculationRulesDocumentRulesForTest enable_document_rules_{true};
+
+  DummyPageHolder page_holder;
+  StubSpeculationHost speculation_host;
+  Document& document = page_holder.GetDocument();
+
+  const KURL kUrl1{"https://example.com/prefetch/list/page1.html"};
+  const KURL kUrl2{"https://example.com/prefetch/document/page1.html"};
+  const KURL kUrl3{"https://example.com/prerender/list/page1.html"};
+  const KURL kUrl4{"https://example.com/prerender/document/page1.html"};
+  const KURL kUrl5{"https://example.com/prefetch/list/page2.html"};
+  const KURL kUrl6{"https://example.com/prefetch/document/page2.html"};
+  const KURL kUrl7{"https://example.com/prerender/list/page2.html"};
+  const KURL kUrl8{"https://example.com/prerender/document/page2.html"};
+
+  AddAnchor(*document.body(), kUrl2.GetString());
+  AddAnchor(*document.body(), kUrl4.GetString());
+  AddAnchor(*document.body(), kUrl6.GetString());
+  AddAnchor(*document.body(), kUrl8.GetString());
+
+  String speculation_script = R"({
+        "prefetch": [
+          {
+            "source": "list",
+            "urls": ["https://example.com/prefetch/list/page1.html"],
+            "eagerness": "conservative"
+          },
+          {
+            "source": "document",
+            "eagerness": "eager",
+            "where": {"href_matches": "https://example.com/prefetch/document/page1.html"}
+          },
+          {
+            "source": "list",
+            "urls": ["https://example.com/prefetch/list/page2.html"]
+          },
+          {
+            "source": "document",
+            "where": {"href_matches": "https://example.com/prefetch/document/page2.html"}
+          }
+        ],
+        "prerender": [
+          {
+            "eagerness": "moderate",
+            "source": "list",
+            "urls": ["https://example.com/prerender/list/page1.html"]
+          },
+          {
+            "source": "document",
+            "where": {"href_matches": "https://example.com/prerender/document/page1.html"},
+            "eagerness": "eager"
+          },
+          {
+            "source": "list",
+            "urls": ["https://example.com/prerender/list/page2.html"]
+          },
+          {
+            "source": "document",
+            "where": {"href_matches": "https://example.com/prerender/document/page2.html"}
+          }
+        ]
+      })";
+  PropagateRulesToStubSpeculationHost(page_holder, speculation_host,
+                                      speculation_script);
+  const auto& candidates = speculation_host.candidates();
+  EXPECT_THAT(
+      candidates,
+      UnorderedElementsAre(
+          AllOf(
+              HasURL(kUrl1),
+              HasEagerness(blink::mojom::SpeculationEagerness::kConservative)),
+          AllOf(HasURL(kUrl2),
+                HasEagerness(blink::mojom::SpeculationEagerness::kEager)),
+          AllOf(HasURL(kUrl3),
+                HasEagerness(blink::mojom::SpeculationEagerness::kModerate)),
+          AllOf(HasURL(kUrl4),
+                HasEagerness(blink::mojom::SpeculationEagerness::kEager)),
+          AllOf(HasURL(kUrl5),
+                HasEagerness(blink::mojom::SpeculationEagerness::kEager)),
+          AllOf(
+              HasURL(kUrl6),
+              HasEagerness(blink::mojom::SpeculationEagerness::kConservative)),
+          AllOf(HasURL(kUrl7),
+                HasEagerness(blink::mojom::SpeculationEagerness::kEager)),
+          AllOf(HasURL(kUrl8),
+                HasEagerness(
+                    blink::mojom::SpeculationEagerness::kConservative))));
+}
+
+TEST_F(SpeculationRuleSetTest, InvalidUseOfEagerness1) {
+  ScopedSpeculationRulesEagernessForTest enable_eagerness{true};
+
+  DummyPageHolder page_holder;
+  StubSpeculationHost speculation_host;
+
+  const char* kUrl1 = "https://example.com/prefetch/list/page1.html";
+
+  String speculation_script = R"({
+        "eagerness": "conservative",
+        "prefetch": [
+          {
+            "source": "list",
+            "urls": ["https://example.com/prefetch/list/page1.html"]
+          }
+        ]
+      })";
+  PropagateRulesToStubSpeculationHost(page_holder, speculation_host,
+                                      speculation_script);
+  const auto& candidates = speculation_host.candidates();
+  // It should just ignore the "eagerness" key
+  EXPECT_THAT(candidates, HasURLs(KURL(kUrl1)));
+}
+
+TEST_F(SpeculationRuleSetTest, InvalidUseOfEagerness2) {
+  ScopedSpeculationRulesEagernessForTest enable_eagerness{true};
+
+  DummyPageHolder page_holder;
+  StubSpeculationHost speculation_host;
+
+  const char* kUrl1 = "https://example.com/prefetch/list/page1.html";
+
+  String speculation_script = R"({
+        "prefetch": [
+          "eagerness",
+          {
+            "source": "list",
+            "urls": ["https://example.com/prefetch/list/page1.html"]
+          }
+        ]
+      })";
+  PropagateRulesToStubSpeculationHost(page_holder, speculation_host,
+                                      speculation_script);
+  const auto& candidates = speculation_host.candidates();
+  // It should just ignore the "eagerness" key
+  EXPECT_THAT(candidates, HasURLs(KURL(kUrl1)));
+}
+
+TEST_F(SpeculationRuleSetTest, InvalidEagernessValue) {
+  ScopedSpeculationRulesEagernessForTest enable_eagerness{true};
+
+  DummyPageHolder page_holder;
+  StubSpeculationHost speculation_host;
+
+  String speculation_script = R"({
+        "prefetch": [
+          {
+            "source": "list",
+            "urls": ["https://example.com/prefetch/list/page1.html"],
+            "eagerness": 0
+          },
+          {
+            "eagerness": 1.0,
+            "source": "list",
+            "urls": ["https://example.com/prefetch/list/page2.html"]
+          },
+          {
+            "source": "list",
+            "eagerness": true,
+            "urls": ["https://example.com/prefetch/list/page3.html"]
+          },
+          {
+            "source": "list",
+            "urls": ["https://example.com/prefetch/list/page4.html"],
+            "eagerness": "xyz"
+          }
+        ]
+      })";
+  PropagateRulesToStubSpeculationHost(page_holder, speculation_host,
+                                      speculation_script);
+  const auto& candidates = speculation_host.candidates();
+  EXPECT_TRUE(candidates.empty());
+}
+
 }  // namespace
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
index 80f7a0c..eb842caf 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -1235,8 +1235,10 @@
   if (GetNode()->HasTagName(html_names::kStrongTag))
     return ax::mojom::blink::Role::kStrong;
 
-  if (GetNode()->HasTagName(html_names::kDelTag))
+  if (GetNode()->HasTagName(html_names::kDelTag) ||
+      GetNode()->HasTagName(html_names::kSTag)) {
     return ax::mojom::blink::Role::kContentDeletion;
+  }
 
   if (GetNode()->HasTagName(html_names::kInsTag))
     return ax::mojom::blink::Role::kContentInsertion;
diff --git a/third_party/blink/renderer/modules/buckets/storage_bucket.idl b/third_party/blink/renderer/modules/buckets/storage_bucket.idl
index 3cbd16e..43e80a54 100644
--- a/third_party/blink/renderer/modules/buckets/storage_bucket.idl
+++ b/third_party/blink/renderer/modules/buckets/storage_bucket.idl
@@ -22,7 +22,7 @@
 
   [SameObject] readonly attribute IDBFactory indexedDB;
 
-  [SameObject] readonly attribute LockManager locks;
+  [SameObject, RuntimeEnabled=StorageBucketsLocks] readonly attribute LockManager locks;
 
   [SameObject, RaisesException] readonly attribute CacheStorage caches;
 
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_database.cc b/third_party/blink/renderer/modules/indexeddb/idb_database.cc
index 53e7aae9..75b35b5 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_database.cc
+++ b/third_party/blink/renderer/modules/indexeddb/idb_database.cc
@@ -562,6 +562,11 @@
 void IDBDatabase::ContextEnteredBackForwardCache() {
   if (base::FeatureList::IsEnabled(
           features::kAllowPageWithIDBTransactionInBFCache)) {
+    CHECK(base::FeatureList::IsEnabled(
+        features::kAllowPageWithIDBConnectionInBFCache))
+        << "kAllowPageWithIDBTransactionInBFCache should only be turned on "
+           "when kAllowPageWithIDBConnectionInBFCache is on.";
+
     if (backend_) {
       backend_->DidBecomeInactive();
     }
diff --git a/third_party/blink/renderer/modules/modules_initializer.cc b/third_party/blink/renderer/modules/modules_initializer.cc
index 47fa43f..8d72cfd 100644
--- a/third_party/blink/renderer/modules/modules_initializer.cc
+++ b/third_party/blink/renderer/modules/modules_initializer.cc
@@ -286,9 +286,9 @@
   session->CreateAndAppend<InspectorAccessibilityAgent>(inspected_frames,
                                                         dom_agent);
   session->CreateAndAppend<InspectorWebAudioAgent>(page);
+  session->CreateAndAppend<InspectorCacheStorageAgent>(inspected_frames);
   if (allow_view_agents) {
     session->CreateAndAppend<InspectorDatabaseAgent>(page);
-    session->CreateAndAppend<InspectorCacheStorageAgent>(inspected_frames);
   }
 }
 
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc
index 0b1b75f..15e55a8 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc
@@ -323,6 +323,12 @@
   texture_descriptor_.viewFormats = view_formats_.get();
   texture_descriptor_.viewFormatCount = descriptor->viewFormats().size();
 
+  // Set the size of the texture in case there was no Reshape() since the
+  // creation of the context.
+  gfx::Size host_size = Host()->Size();
+  texture_descriptor_.size = {static_cast<uint32_t>(host_size.width()),
+                              static_cast<uint32_t>(host_size.height()), 1};
+
   // This needs to happen early so that if any validation fails the swapbuffers
   // are not created and getCurrentTexture() will return an error GPUTexture.
   DetachSwapBuffers();
@@ -331,6 +337,13 @@
   // that errors can be generated in the appropriate error scope.
   device_ = descriptor->device();
 
+  // The WebGPU spec requires that a validation error be produced if the
+  // descriptor is invalid. However no call to AssociateMailbox is done in
+  // configure() which would produce the error. Directly request that the
+  // descriptor be validated instead.
+  device_->GetProcs().deviceValidateTextureDescriptor(device_->GetHandle(),
+                                                      &texture_descriptor_);
+
   switch (texture_descriptor_.format) {
     // TODO(crbug.com/1361468): support BGRA8Unorm on Android.
 #if !BUILDFLAG(IS_ANDROID)
@@ -346,8 +359,11 @@
 #endif
       break;
     default:
-      device_->InjectError(WGPUErrorType_Validation,
-                           "unsupported swap chain format");
+      device_->InjectError(
+          WGPUErrorType_Validation,
+          ("unsupported swap chain format \"" +
+           std::string(FromDawnEnum(texture_descriptor_.format)) + "\"")
+              .c_str());
       return;
   }
 
@@ -427,9 +443,7 @@
     ResizeSwapbuffers(configured_size_);
   } else {
     configured_size_.SetSize(0, 0);
-
-    gfx::Size size = Host()->Size();
-    ResizeSwapbuffers(size);
+    ResizeSwapbuffers(host_size);
   }
 }
 
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_lab_color_space.h b/third_party/blink/renderer/platform/graphics/dark_mode_lab_color_space.h
index 999c3e5b..28a15cd 100644
--- a/third_party/blink/renderer/platform/graphics/dark_mode_lab_color_space.h
+++ b/third_party/blink/renderer/platform/graphics/dark_mode_lab_color_space.h
@@ -125,8 +125,7 @@
   // https://en.wikipedia.org/wiki/CIELAB_color_space#Reverse_transformation.
   SkV3 FromXYZ(const SkV3& v) const {
     auto f = [](float x) {
-      return x > kSigma3 ? pow(x, 1.0f / 3.0f)
-                         : x / (3 * kSigma2) + 4.0f / 29.0f;
+      return x > kSigma3 ? std::cbrt(x) : x / (3 * kSigma2) + 4.0f / 29.0f;
     };
 
     float fx = f(v.x / kIlluminantD50.x);
@@ -145,7 +144,7 @@
   // https://en.wikipedia.org/wiki/CIELAB_color_space#Forward_transformation.
   SkV3 ToXYZ(const SkV3& lab) const {
     auto invf = [](float x) {
-      return x > kSigma ? pow(x, 3.0f) : 3.0f * kSigma2 * (x - 4.0f / 29.0f);
+      return x > kSigma ? x * x * x : 3.0f * kSigma2 * (x - 4.0f / 29.0f);
     };
 
     SkV3 v = {Clamp(lab.x, 0.0f, 100.0f), Clamp(lab.y, -128.0f, 128.0f),
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 9300257..7dd0cc0 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1525,12 +1525,6 @@
       base_feature: "HTMLMapToImgMatchingByNameAndId",
     },
     {
-      // TODO(crbug.com/1315717): This flag is being used to deprecate support for <param> urls within <object> elements. This feature is controlled by blink::features::kHTMLParamElementUrlSupport.
-      name: "HTMLParamElementUrlSupport",
-      status: "stable",
-      base_feature: "HTMLParamElementUrlSupport",
-    },
-    {
       // TODO(crbug.com/1307772): Enables the Popover API.
       name: "HTMLPopoverAttribute",
       status: "experimental",
@@ -2644,6 +2638,12 @@
       origin_trial_allows_third_party: true,
     },
     {
+      name: "SpeculationRulesDocumentRulesSelectorMatches",
+    },
+    {
+      name: "SpeculationRulesEagerness",
+    },
+    {
       name: "SpeculationRulesFetchFromHeader",
       origin_trial_feature_name: "SpeculationRulesPrefetchFuture",
       origin_trial_allows_third_party: true,
@@ -2721,6 +2721,12 @@
       base_feature: "StorageBuckets",
     },
     {
+      // Gates the `locks()` method on a storage bucket.
+      name: "StorageBucketsLocks",
+      status: "experimental",
+      base_feature: "StorageBucketsLocks",
+    },
+    {
       name: "StreamingDeclarativeShadowDOM",
       status: "experimental",
       base_feature: "StreamingDeclarativeShadowDOM",
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 2574d20..a42c118 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -3863,14 +3863,6 @@
 
 # Flaky Windows-only content_shell crash
 
-# Temporarily disable failing cookie control character tests until we implement
-# the latest spec changes. Specifically, 0x00, 0x0d and 0x0a should cause
-# cookie rejection instead of truncation, and the tab character should be
-# treated as a valid character.
-crbug.com/1233602 external/wpt/cookies/attributes/attributes-ctl.sub.html [ Failure ]
-crbug.com/1233602 external/wpt/cookies/name/name-ctl.html [ Failure ]
-crbug.com/1233602 external/wpt/cookies/value/value-ctl.html [ Failure ]
-
 # The virtual tests run with Schemeful Same-Site disabled. These should fail to ensure the disabled feature code paths work.
 crbug.com/1127348 virtual/schemeful-same-site/external/wpt/cookies/schemeful-same-site/schemeful-websockets.sub.tentative.html [ Failure ]
 crbug.com/1127348 virtual/schemeful-same-site/external/wpt/cookies/schemeful-same-site/schemeful-iframe-subresource.tentative.html [ Failure ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
index 37c9238..d38d68f 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -262136,11 +262136,11 @@
   "support": {
    ".cache": {
     "gitignore2.json": [
-     "e6d5acf17ccf6564a225bc1d56882181e872ff2b",
+     "2b75c2b4d2d25a7e59b0e33de8a4d06bbc53a3c5",
      []
     ],
     "mtime.json": [
-     "38638db6febd1901e479ade46260626cd3d4dfe9",
+     "2acbd14bcd43dc2ad427d067bc608109577425da",
      []
     ]
    },
@@ -323959,14 +323959,26 @@
        "cfa46fa9706127e00580cf1e1c5f022bc8563538",
        []
       ],
+      "kind-of-widget-fallback-input-search-text-border-start-end-radius-001.html.ini": [
+       "71e3df2aca79ef1b9533880d6cb47dc43226c386",
+       []
+      ],
       "kind-of-widget-fallback-input-submit-border-block-end-color-001.html.ini": [
        "305b0c2ca7921e6e111f3d79e6cec8a6db081e5a",
        []
       ],
+      "kind-of-widget-fallback-input-submit-border-inline-end-width-001.html.ini": [
+       "2a170629651d9defa1951ceceeab784ca50ea285",
+       []
+      ],
       "kind-of-widget-fallback-input-submit-border-inline-start-style-001.html.ini": [
        "57acbdd3666e3a4965d10651a009475c0449b77c",
        []
       ],
+      "kind-of-widget-fallback-input-text-border-right-color-001.html.ini": [
+       "5bc373383d5976f2a3ac4ad63256a3003a52ab54",
+       []
+      ],
       "kind-of-widget-fallback-meter-background-attachment-001.html.ini": [
        "5c85d4c8e2f214d8e5287e8ac98f6b1d3a9a274c",
        []
@@ -352223,7 +352235,7 @@
         []
        ],
        "access-to-coop-page-from-other_coop-ro_cross-origin.https.html.ini": [
-        "81a4bcfdff5cb849edf2ce90e90df4a01de2d46c",
+        "749a9f846614b947ef5a46ef7b9b27aa54c06edb",
         []
        ],
        "property-blur.https.html.ini": [
@@ -377544,7 +377556,7 @@
      []
     ],
     "content-type-parsing.html.ini": [
-     "a642e44e80f2a5ed007637e437a811a2bf80c340",
+     "2eadb5900b1ebb7e5165b71d8735dfbb69cae4e0",
      []
     ],
     "frameset-timing.html": [
@@ -394638,6 +394650,10 @@
         "754eed88b7ac420bb8cf07fa15cc0867d80e80fa",
         []
        ],
+       "embedded_style_selectors.html.ini": [
+        "e65e2f5942e3182d73a1bbfc5dc6ab9cab595338",
+        []
+       ],
        "embedded_style_urls-ref.html": [
         "6eca04506e1168680a9787c2b7999fc28bf26c22",
         []
@@ -448716,6 +448732,13 @@
         {}
        ]
       ],
+      "custom-property-transition-mismatched-inherited-property-numbers.html": [
+       "292e23b1fe6f76eaf715ed6ed3693a6b229254c4",
+       [
+        null,
+        {}
+       ]
+      ],
       "custom-property-transition-mismatched-list.html": [
        "7796e36a2e38f6074113dff3e20498b33ecf8c7a",
        [
diff --git a/third_party/blink/web_tests/external/wpt/cookies/attributes/attributes-ctl.sub-expected.txt b/third_party/blink/web_tests/external/wpt/cookies/attributes/attributes-ctl.sub-expected.txt
new file mode 100644
index 0000000..caa52f3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/cookies/attributes/attributes-ctl.sub-expected.txt
@@ -0,0 +1,433 @@
+This is a testharness.js-based test.
+Found 429 tests; 391 PASS, 38 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS Cookie with %x0 in Domain attribute value is handled correctly.
+FAIL Cookie with %x0 after Domain attribute value is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test0domain2=t"
+PASS Cookie with %x0 in Path attribute value is handled correctly.
+FAIL Cookie with %x0 after Path attribute value is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test0path2=t"
+FAIL Cookie with %x0 in Max-Age attribute value is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test0maxage=t"
+FAIL Cookie with %x0 after Max-Age attribute value is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test0maxage2=t"
+FAIL Cookie with %x0 in Expires attribute value is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test0expires=t"
+FAIL Cookie with %x0 after Expires attribute value is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test0expires2=t"
+FAIL Cookie with %x0 in Secure attribute is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test0secure=t"
+PASS Cookie with %x0 after Secure attribute is handled correctly.
+FAIL Cookie with %x0 in HttpOnly attribute is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test0httponly=t"
+FAIL Cookie with %x0 in SameSite attribute value is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test0samesite=t"
+FAIL Cookie with %x0 after SameSite attribute value is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test0samesite2=t"
+PASS Cookie with %x1 in Domain attribute value is handled correctly.
+PASS Cookie with %x1 after Domain attribute value is handled correctly.
+PASS Cookie with %x1 in Path attribute value is handled correctly.
+PASS Cookie with %x1 after Path attribute value is handled correctly.
+PASS Cookie with %x1 in Max-Age attribute value is handled correctly.
+PASS Cookie with %x1 after Max-Age attribute value is handled correctly.
+PASS Cookie with %x1 in Expires attribute value is handled correctly.
+PASS Cookie with %x1 after Expires attribute value is handled correctly.
+PASS Cookie with %x1 in Secure attribute is handled correctly.
+PASS Cookie with %x1 after Secure attribute is handled correctly.
+PASS Cookie with %x1 in HttpOnly attribute is handled correctly.
+PASS Cookie with %x1 in SameSite attribute value is handled correctly.
+PASS Cookie with %x1 after SameSite attribute value is handled correctly.
+PASS Cookie with %x2 in Domain attribute value is handled correctly.
+PASS Cookie with %x2 after Domain attribute value is handled correctly.
+PASS Cookie with %x2 in Path attribute value is handled correctly.
+PASS Cookie with %x2 after Path attribute value is handled correctly.
+PASS Cookie with %x2 in Max-Age attribute value is handled correctly.
+PASS Cookie with %x2 after Max-Age attribute value is handled correctly.
+PASS Cookie with %x2 in Expires attribute value is handled correctly.
+PASS Cookie with %x2 after Expires attribute value is handled correctly.
+PASS Cookie with %x2 in Secure attribute is handled correctly.
+PASS Cookie with %x2 after Secure attribute is handled correctly.
+PASS Cookie with %x2 in HttpOnly attribute is handled correctly.
+PASS Cookie with %x2 in SameSite attribute value is handled correctly.
+PASS Cookie with %x2 after SameSite attribute value is handled correctly.
+PASS Cookie with %x3 in Domain attribute value is handled correctly.
+PASS Cookie with %x3 after Domain attribute value is handled correctly.
+PASS Cookie with %x3 in Path attribute value is handled correctly.
+PASS Cookie with %x3 after Path attribute value is handled correctly.
+PASS Cookie with %x3 in Max-Age attribute value is handled correctly.
+PASS Cookie with %x3 after Max-Age attribute value is handled correctly.
+PASS Cookie with %x3 in Expires attribute value is handled correctly.
+PASS Cookie with %x3 after Expires attribute value is handled correctly.
+PASS Cookie with %x3 in Secure attribute is handled correctly.
+PASS Cookie with %x3 after Secure attribute is handled correctly.
+PASS Cookie with %x3 in HttpOnly attribute is handled correctly.
+PASS Cookie with %x3 in SameSite attribute value is handled correctly.
+PASS Cookie with %x3 after SameSite attribute value is handled correctly.
+PASS Cookie with %x4 in Domain attribute value is handled correctly.
+PASS Cookie with %x4 after Domain attribute value is handled correctly.
+PASS Cookie with %x4 in Path attribute value is handled correctly.
+PASS Cookie with %x4 after Path attribute value is handled correctly.
+PASS Cookie with %x4 in Max-Age attribute value is handled correctly.
+PASS Cookie with %x4 after Max-Age attribute value is handled correctly.
+PASS Cookie with %x4 in Expires attribute value is handled correctly.
+PASS Cookie with %x4 after Expires attribute value is handled correctly.
+PASS Cookie with %x4 in Secure attribute is handled correctly.
+PASS Cookie with %x4 after Secure attribute is handled correctly.
+PASS Cookie with %x4 in HttpOnly attribute is handled correctly.
+PASS Cookie with %x4 in SameSite attribute value is handled correctly.
+PASS Cookie with %x4 after SameSite attribute value is handled correctly.
+PASS Cookie with %x5 in Domain attribute value is handled correctly.
+PASS Cookie with %x5 after Domain attribute value is handled correctly.
+PASS Cookie with %x5 in Path attribute value is handled correctly.
+PASS Cookie with %x5 after Path attribute value is handled correctly.
+PASS Cookie with %x5 in Max-Age attribute value is handled correctly.
+PASS Cookie with %x5 after Max-Age attribute value is handled correctly.
+PASS Cookie with %x5 in Expires attribute value is handled correctly.
+PASS Cookie with %x5 after Expires attribute value is handled correctly.
+PASS Cookie with %x5 in Secure attribute is handled correctly.
+PASS Cookie with %x5 after Secure attribute is handled correctly.
+PASS Cookie with %x5 in HttpOnly attribute is handled correctly.
+PASS Cookie with %x5 in SameSite attribute value is handled correctly.
+PASS Cookie with %x5 after SameSite attribute value is handled correctly.
+PASS Cookie with %x6 in Domain attribute value is handled correctly.
+PASS Cookie with %x6 after Domain attribute value is handled correctly.
+PASS Cookie with %x6 in Path attribute value is handled correctly.
+PASS Cookie with %x6 after Path attribute value is handled correctly.
+PASS Cookie with %x6 in Max-Age attribute value is handled correctly.
+PASS Cookie with %x6 after Max-Age attribute value is handled correctly.
+PASS Cookie with %x6 in Expires attribute value is handled correctly.
+PASS Cookie with %x6 after Expires attribute value is handled correctly.
+PASS Cookie with %x6 in Secure attribute is handled correctly.
+PASS Cookie with %x6 after Secure attribute is handled correctly.
+PASS Cookie with %x6 in HttpOnly attribute is handled correctly.
+PASS Cookie with %x6 in SameSite attribute value is handled correctly.
+PASS Cookie with %x6 after SameSite attribute value is handled correctly.
+PASS Cookie with %x7 in Domain attribute value is handled correctly.
+PASS Cookie with %x7 after Domain attribute value is handled correctly.
+PASS Cookie with %x7 in Path attribute value is handled correctly.
+PASS Cookie with %x7 after Path attribute value is handled correctly.
+PASS Cookie with %x7 in Max-Age attribute value is handled correctly.
+PASS Cookie with %x7 after Max-Age attribute value is handled correctly.
+PASS Cookie with %x7 in Expires attribute value is handled correctly.
+PASS Cookie with %x7 after Expires attribute value is handled correctly.
+PASS Cookie with %x7 in Secure attribute is handled correctly.
+PASS Cookie with %x7 after Secure attribute is handled correctly.
+PASS Cookie with %x7 in HttpOnly attribute is handled correctly.
+PASS Cookie with %x7 in SameSite attribute value is handled correctly.
+PASS Cookie with %x7 after SameSite attribute value is handled correctly.
+PASS Cookie with %x8 in Domain attribute value is handled correctly.
+PASS Cookie with %x8 after Domain attribute value is handled correctly.
+PASS Cookie with %x8 in Path attribute value is handled correctly.
+PASS Cookie with %x8 after Path attribute value is handled correctly.
+PASS Cookie with %x8 in Max-Age attribute value is handled correctly.
+PASS Cookie with %x8 after Max-Age attribute value is handled correctly.
+PASS Cookie with %x8 in Expires attribute value is handled correctly.
+PASS Cookie with %x8 after Expires attribute value is handled correctly.
+PASS Cookie with %x8 in Secure attribute is handled correctly.
+PASS Cookie with %x8 after Secure attribute is handled correctly.
+PASS Cookie with %x8 in HttpOnly attribute is handled correctly.
+PASS Cookie with %x8 in SameSite attribute value is handled correctly.
+PASS Cookie with %x8 after SameSite attribute value is handled correctly.
+FAIL Cookie with %x9 in Domain attribute value is handled correctly. assert_equals: The cookie was set as expected. expected "test9domain=t" but got ""
+PASS Cookie with %x9 after Domain attribute value is handled correctly.
+FAIL Cookie with %x9 in Path attribute value is handled correctly. assert_equals: The cookie was set as expected. expected "test9path=t" but got ""
+PASS Cookie with %x9 after Path attribute value is handled correctly.
+FAIL Cookie with %x9 in Max-Age attribute value is handled correctly. assert_equals: The cookie was set as expected. expected "test9maxage=t" but got ""
+PASS Cookie with %x9 after Max-Age attribute value is handled correctly.
+FAIL Cookie with %x9 in Expires attribute value is handled correctly. assert_equals: The cookie was set as expected. expected "test9expires=t" but got ""
+PASS Cookie with %x9 after Expires attribute value is handled correctly.
+FAIL Cookie with %x9 in Secure attribute is handled correctly. assert_equals: The cookie was set as expected. expected "test9secure=t" but got ""
+FAIL Cookie with %x9 after Secure attribute is handled correctly. assert_equals: The cookie was set as expected. expected "test9secure2=t" but got ""
+FAIL Cookie with %x9 in HttpOnly attribute is handled correctly. assert_equals: The cookie was set as expected. expected "test9httponly=t" but got ""
+FAIL Cookie with %x9 in SameSite attribute value is handled correctly. assert_equals: The cookie was set as expected. expected "test9samesite=t" but got ""
+PASS Cookie with %x9 after SameSite attribute value is handled correctly.
+PASS Cookie with %xa in Domain attribute value is handled correctly.
+FAIL Cookie with %xa after Domain attribute value is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test10domain2=t"
+PASS Cookie with %xa in Path attribute value is handled correctly.
+FAIL Cookie with %xa after Path attribute value is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test10path2=t"
+FAIL Cookie with %xa in Max-Age attribute value is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test10maxage=t"
+FAIL Cookie with %xa after Max-Age attribute value is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test10maxage2=t"
+FAIL Cookie with %xa in Expires attribute value is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test10expires=t"
+FAIL Cookie with %xa after Expires attribute value is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test10expires2=t"
+FAIL Cookie with %xa in Secure attribute is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test10secure=t"
+PASS Cookie with %xa after Secure attribute is handled correctly.
+FAIL Cookie with %xa in HttpOnly attribute is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test10httponly=t"
+FAIL Cookie with %xa in SameSite attribute value is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test10samesite=t"
+FAIL Cookie with %xa after SameSite attribute value is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test10samesite2=t"
+PASS Cookie with %xb in Domain attribute value is handled correctly.
+PASS Cookie with %xb after Domain attribute value is handled correctly.
+PASS Cookie with %xb in Path attribute value is handled correctly.
+PASS Cookie with %xb after Path attribute value is handled correctly.
+PASS Cookie with %xb in Max-Age attribute value is handled correctly.
+PASS Cookie with %xb after Max-Age attribute value is handled correctly.
+PASS Cookie with %xb in Expires attribute value is handled correctly.
+PASS Cookie with %xb after Expires attribute value is handled correctly.
+PASS Cookie with %xb in Secure attribute is handled correctly.
+PASS Cookie with %xb after Secure attribute is handled correctly.
+PASS Cookie with %xb in HttpOnly attribute is handled correctly.
+PASS Cookie with %xb in SameSite attribute value is handled correctly.
+PASS Cookie with %xb after SameSite attribute value is handled correctly.
+PASS Cookie with %xc in Domain attribute value is handled correctly.
+PASS Cookie with %xc after Domain attribute value is handled correctly.
+PASS Cookie with %xc in Path attribute value is handled correctly.
+PASS Cookie with %xc after Path attribute value is handled correctly.
+PASS Cookie with %xc in Max-Age attribute value is handled correctly.
+PASS Cookie with %xc after Max-Age attribute value is handled correctly.
+PASS Cookie with %xc in Expires attribute value is handled correctly.
+PASS Cookie with %xc after Expires attribute value is handled correctly.
+PASS Cookie with %xc in Secure attribute is handled correctly.
+PASS Cookie with %xc after Secure attribute is handled correctly.
+PASS Cookie with %xc in HttpOnly attribute is handled correctly.
+PASS Cookie with %xc in SameSite attribute value is handled correctly.
+PASS Cookie with %xc after SameSite attribute value is handled correctly.
+PASS Cookie with %xd in Domain attribute value is handled correctly.
+FAIL Cookie with %xd after Domain attribute value is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test13domain2=t"
+PASS Cookie with %xd in Path attribute value is handled correctly.
+FAIL Cookie with %xd after Path attribute value is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test13path2=t"
+FAIL Cookie with %xd in Max-Age attribute value is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test13maxage=t"
+FAIL Cookie with %xd after Max-Age attribute value is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test13maxage2=t"
+FAIL Cookie with %xd in Expires attribute value is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test13expires=t"
+FAIL Cookie with %xd after Expires attribute value is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test13expires2=t"
+FAIL Cookie with %xd in Secure attribute is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test13secure=t"
+PASS Cookie with %xd after Secure attribute is handled correctly.
+FAIL Cookie with %xd in HttpOnly attribute is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test13httponly=t"
+FAIL Cookie with %xd in SameSite attribute value is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test13samesite=t"
+FAIL Cookie with %xd after SameSite attribute value is handled correctly. assert_equals: The cookie was rejected. expected "" but got "test13samesite2=t"
+PASS Cookie with %xe in Domain attribute value is handled correctly.
+PASS Cookie with %xe after Domain attribute value is handled correctly.
+PASS Cookie with %xe in Path attribute value is handled correctly.
+PASS Cookie with %xe after Path attribute value is handled correctly.
+PASS Cookie with %xe in Max-Age attribute value is handled correctly.
+PASS Cookie with %xe after Max-Age attribute value is handled correctly.
+PASS Cookie with %xe in Expires attribute value is handled correctly.
+PASS Cookie with %xe after Expires attribute value is handled correctly.
+PASS Cookie with %xe in Secure attribute is handled correctly.
+PASS Cookie with %xe after Secure attribute is handled correctly.
+PASS Cookie with %xe in HttpOnly attribute is handled correctly.
+PASS Cookie with %xe in SameSite attribute value is handled correctly.
+PASS Cookie with %xe after SameSite attribute value is handled correctly.
+PASS Cookie with %xf in Domain attribute value is handled correctly.
+PASS Cookie with %xf after Domain attribute value is handled correctly.
+PASS Cookie with %xf in Path attribute value is handled correctly.
+PASS Cookie with %xf after Path attribute value is handled correctly.
+PASS Cookie with %xf in Max-Age attribute value is handled correctly.
+PASS Cookie with %xf after Max-Age attribute value is handled correctly.
+PASS Cookie with %xf in Expires attribute value is handled correctly.
+PASS Cookie with %xf after Expires attribute value is handled correctly.
+PASS Cookie with %xf in Secure attribute is handled correctly.
+PASS Cookie with %xf after Secure attribute is handled correctly.
+PASS Cookie with %xf in HttpOnly attribute is handled correctly.
+PASS Cookie with %xf in SameSite attribute value is handled correctly.
+PASS Cookie with %xf after SameSite attribute value is handled correctly.
+PASS Cookie with %x10 in Domain attribute value is handled correctly.
+PASS Cookie with %x10 after Domain attribute value is handled correctly.
+PASS Cookie with %x10 in Path attribute value is handled correctly.
+PASS Cookie with %x10 after Path attribute value is handled correctly.
+PASS Cookie with %x10 in Max-Age attribute value is handled correctly.
+PASS Cookie with %x10 after Max-Age attribute value is handled correctly.
+PASS Cookie with %x10 in Expires attribute value is handled correctly.
+PASS Cookie with %x10 after Expires attribute value is handled correctly.
+PASS Cookie with %x10 in Secure attribute is handled correctly.
+PASS Cookie with %x10 after Secure attribute is handled correctly.
+PASS Cookie with %x10 in HttpOnly attribute is handled correctly.
+PASS Cookie with %x10 in SameSite attribute value is handled correctly.
+PASS Cookie with %x10 after SameSite attribute value is handled correctly.
+PASS Cookie with %x11 in Domain attribute value is handled correctly.
+PASS Cookie with %x11 after Domain attribute value is handled correctly.
+PASS Cookie with %x11 in Path attribute value is handled correctly.
+PASS Cookie with %x11 after Path attribute value is handled correctly.
+PASS Cookie with %x11 in Max-Age attribute value is handled correctly.
+PASS Cookie with %x11 after Max-Age attribute value is handled correctly.
+PASS Cookie with %x11 in Expires attribute value is handled correctly.
+PASS Cookie with %x11 after Expires attribute value is handled correctly.
+PASS Cookie with %x11 in Secure attribute is handled correctly.
+PASS Cookie with %x11 after Secure attribute is handled correctly.
+PASS Cookie with %x11 in HttpOnly attribute is handled correctly.
+PASS Cookie with %x11 in SameSite attribute value is handled correctly.
+PASS Cookie with %x11 after SameSite attribute value is handled correctly.
+PASS Cookie with %x12 in Domain attribute value is handled correctly.
+PASS Cookie with %x12 after Domain attribute value is handled correctly.
+PASS Cookie with %x12 in Path attribute value is handled correctly.
+PASS Cookie with %x12 after Path attribute value is handled correctly.
+PASS Cookie with %x12 in Max-Age attribute value is handled correctly.
+PASS Cookie with %x12 after Max-Age attribute value is handled correctly.
+PASS Cookie with %x12 in Expires attribute value is handled correctly.
+PASS Cookie with %x12 after Expires attribute value is handled correctly.
+PASS Cookie with %x12 in Secure attribute is handled correctly.
+PASS Cookie with %x12 after Secure attribute is handled correctly.
+PASS Cookie with %x12 in HttpOnly attribute is handled correctly.
+PASS Cookie with %x12 in SameSite attribute value is handled correctly.
+PASS Cookie with %x12 after SameSite attribute value is handled correctly.
+PASS Cookie with %x13 in Domain attribute value is handled correctly.
+PASS Cookie with %x13 after Domain attribute value is handled correctly.
+PASS Cookie with %x13 in Path attribute value is handled correctly.
+PASS Cookie with %x13 after Path attribute value is handled correctly.
+PASS Cookie with %x13 in Max-Age attribute value is handled correctly.
+PASS Cookie with %x13 after Max-Age attribute value is handled correctly.
+PASS Cookie with %x13 in Expires attribute value is handled correctly.
+PASS Cookie with %x13 after Expires attribute value is handled correctly.
+PASS Cookie with %x13 in Secure attribute is handled correctly.
+PASS Cookie with %x13 after Secure attribute is handled correctly.
+PASS Cookie with %x13 in HttpOnly attribute is handled correctly.
+PASS Cookie with %x13 in SameSite attribute value is handled correctly.
+PASS Cookie with %x13 after SameSite attribute value is handled correctly.
+PASS Cookie with %x14 in Domain attribute value is handled correctly.
+PASS Cookie with %x14 after Domain attribute value is handled correctly.
+PASS Cookie with %x14 in Path attribute value is handled correctly.
+PASS Cookie with %x14 after Path attribute value is handled correctly.
+PASS Cookie with %x14 in Max-Age attribute value is handled correctly.
+PASS Cookie with %x14 after Max-Age attribute value is handled correctly.
+PASS Cookie with %x14 in Expires attribute value is handled correctly.
+PASS Cookie with %x14 after Expires attribute value is handled correctly.
+PASS Cookie with %x14 in Secure attribute is handled correctly.
+PASS Cookie with %x14 after Secure attribute is handled correctly.
+PASS Cookie with %x14 in HttpOnly attribute is handled correctly.
+PASS Cookie with %x14 in SameSite attribute value is handled correctly.
+PASS Cookie with %x14 after SameSite attribute value is handled correctly.
+PASS Cookie with %x15 in Domain attribute value is handled correctly.
+PASS Cookie with %x15 after Domain attribute value is handled correctly.
+PASS Cookie with %x15 in Path attribute value is handled correctly.
+PASS Cookie with %x15 after Path attribute value is handled correctly.
+PASS Cookie with %x15 in Max-Age attribute value is handled correctly.
+PASS Cookie with %x15 after Max-Age attribute value is handled correctly.
+PASS Cookie with %x15 in Expires attribute value is handled correctly.
+PASS Cookie with %x15 after Expires attribute value is handled correctly.
+PASS Cookie with %x15 in Secure attribute is handled correctly.
+PASS Cookie with %x15 after Secure attribute is handled correctly.
+PASS Cookie with %x15 in HttpOnly attribute is handled correctly.
+PASS Cookie with %x15 in SameSite attribute value is handled correctly.
+PASS Cookie with %x15 after SameSite attribute value is handled correctly.
+PASS Cookie with %x16 in Domain attribute value is handled correctly.
+PASS Cookie with %x16 after Domain attribute value is handled correctly.
+PASS Cookie with %x16 in Path attribute value is handled correctly.
+PASS Cookie with %x16 after Path attribute value is handled correctly.
+PASS Cookie with %x16 in Max-Age attribute value is handled correctly.
+PASS Cookie with %x16 after Max-Age attribute value is handled correctly.
+PASS Cookie with %x16 in Expires attribute value is handled correctly.
+PASS Cookie with %x16 after Expires attribute value is handled correctly.
+PASS Cookie with %x16 in Secure attribute is handled correctly.
+PASS Cookie with %x16 after Secure attribute is handled correctly.
+PASS Cookie with %x16 in HttpOnly attribute is handled correctly.
+PASS Cookie with %x16 in SameSite attribute value is handled correctly.
+PASS Cookie with %x16 after SameSite attribute value is handled correctly.
+PASS Cookie with %x17 in Domain attribute value is handled correctly.
+PASS Cookie with %x17 after Domain attribute value is handled correctly.
+PASS Cookie with %x17 in Path attribute value is handled correctly.
+PASS Cookie with %x17 after Path attribute value is handled correctly.
+PASS Cookie with %x17 in Max-Age attribute value is handled correctly.
+PASS Cookie with %x17 after Max-Age attribute value is handled correctly.
+PASS Cookie with %x17 in Expires attribute value is handled correctly.
+PASS Cookie with %x17 after Expires attribute value is handled correctly.
+PASS Cookie with %x17 in Secure attribute is handled correctly.
+PASS Cookie with %x17 after Secure attribute is handled correctly.
+PASS Cookie with %x17 in HttpOnly attribute is handled correctly.
+PASS Cookie with %x17 in SameSite attribute value is handled correctly.
+PASS Cookie with %x17 after SameSite attribute value is handled correctly.
+PASS Cookie with %x18 in Domain attribute value is handled correctly.
+PASS Cookie with %x18 after Domain attribute value is handled correctly.
+PASS Cookie with %x18 in Path attribute value is handled correctly.
+PASS Cookie with %x18 after Path attribute value is handled correctly.
+PASS Cookie with %x18 in Max-Age attribute value is handled correctly.
+PASS Cookie with %x18 after Max-Age attribute value is handled correctly.
+PASS Cookie with %x18 in Expires attribute value is handled correctly.
+PASS Cookie with %x18 after Expires attribute value is handled correctly.
+PASS Cookie with %x18 in Secure attribute is handled correctly.
+PASS Cookie with %x18 after Secure attribute is handled correctly.
+PASS Cookie with %x18 in HttpOnly attribute is handled correctly.
+PASS Cookie with %x18 in SameSite attribute value is handled correctly.
+PASS Cookie with %x18 after SameSite attribute value is handled correctly.
+PASS Cookie with %x19 in Domain attribute value is handled correctly.
+PASS Cookie with %x19 after Domain attribute value is handled correctly.
+PASS Cookie with %x19 in Path attribute value is handled correctly.
+PASS Cookie with %x19 after Path attribute value is handled correctly.
+PASS Cookie with %x19 in Max-Age attribute value is handled correctly.
+PASS Cookie with %x19 after Max-Age attribute value is handled correctly.
+PASS Cookie with %x19 in Expires attribute value is handled correctly.
+PASS Cookie with %x19 after Expires attribute value is handled correctly.
+PASS Cookie with %x19 in Secure attribute is handled correctly.
+PASS Cookie with %x19 after Secure attribute is handled correctly.
+PASS Cookie with %x19 in HttpOnly attribute is handled correctly.
+PASS Cookie with %x19 in SameSite attribute value is handled correctly.
+PASS Cookie with %x19 after SameSite attribute value is handled correctly.
+PASS Cookie with %x1a in Domain attribute value is handled correctly.
+PASS Cookie with %x1a after Domain attribute value is handled correctly.
+PASS Cookie with %x1a in Path attribute value is handled correctly.
+PASS Cookie with %x1a after Path attribute value is handled correctly.
+PASS Cookie with %x1a in Max-Age attribute value is handled correctly.
+PASS Cookie with %x1a after Max-Age attribute value is handled correctly.
+PASS Cookie with %x1a in Expires attribute value is handled correctly.
+PASS Cookie with %x1a after Expires attribute value is handled correctly.
+PASS Cookie with %x1a in Secure attribute is handled correctly.
+PASS Cookie with %x1a after Secure attribute is handled correctly.
+PASS Cookie with %x1a in HttpOnly attribute is handled correctly.
+PASS Cookie with %x1a in SameSite attribute value is handled correctly.
+PASS Cookie with %x1a after SameSite attribute value is handled correctly.
+PASS Cookie with %x1b in Domain attribute value is handled correctly.
+PASS Cookie with %x1b after Domain attribute value is handled correctly.
+PASS Cookie with %x1b in Path attribute value is handled correctly.
+PASS Cookie with %x1b after Path attribute value is handled correctly.
+PASS Cookie with %x1b in Max-Age attribute value is handled correctly.
+PASS Cookie with %x1b after Max-Age attribute value is handled correctly.
+PASS Cookie with %x1b in Expires attribute value is handled correctly.
+PASS Cookie with %x1b after Expires attribute value is handled correctly.
+PASS Cookie with %x1b in Secure attribute is handled correctly.
+PASS Cookie with %x1b after Secure attribute is handled correctly.
+PASS Cookie with %x1b in HttpOnly attribute is handled correctly.
+PASS Cookie with %x1b in SameSite attribute value is handled correctly.
+PASS Cookie with %x1b after SameSite attribute value is handled correctly.
+PASS Cookie with %x1c in Domain attribute value is handled correctly.
+PASS Cookie with %x1c after Domain attribute value is handled correctly.
+PASS Cookie with %x1c in Path attribute value is handled correctly.
+PASS Cookie with %x1c after Path attribute value is handled correctly.
+PASS Cookie with %x1c in Max-Age attribute value is handled correctly.
+PASS Cookie with %x1c after Max-Age attribute value is handled correctly.
+PASS Cookie with %x1c in Expires attribute value is handled correctly.
+PASS Cookie with %x1c after Expires attribute value is handled correctly.
+PASS Cookie with %x1c in Secure attribute is handled correctly.
+PASS Cookie with %x1c after Secure attribute is handled correctly.
+PASS Cookie with %x1c in HttpOnly attribute is handled correctly.
+PASS Cookie with %x1c in SameSite attribute value is handled correctly.
+PASS Cookie with %x1c after SameSite attribute value is handled correctly.
+PASS Cookie with %x1d in Domain attribute value is handled correctly.
+PASS Cookie with %x1d after Domain attribute value is handled correctly.
+PASS Cookie with %x1d in Path attribute value is handled correctly.
+PASS Cookie with %x1d after Path attribute value is handled correctly.
+PASS Cookie with %x1d in Max-Age attribute value is handled correctly.
+PASS Cookie with %x1d after Max-Age attribute value is handled correctly.
+PASS Cookie with %x1d in Expires attribute value is handled correctly.
+PASS Cookie with %x1d after Expires attribute value is handled correctly.
+PASS Cookie with %x1d in Secure attribute is handled correctly.
+PASS Cookie with %x1d after Secure attribute is handled correctly.
+PASS Cookie with %x1d in HttpOnly attribute is handled correctly.
+PASS Cookie with %x1d in SameSite attribute value is handled correctly.
+PASS Cookie with %x1d after SameSite attribute value is handled correctly.
+PASS Cookie with %x1e in Domain attribute value is handled correctly.
+PASS Cookie with %x1e after Domain attribute value is handled correctly.
+PASS Cookie with %x1e in Path attribute value is handled correctly.
+PASS Cookie with %x1e after Path attribute value is handled correctly.
+PASS Cookie with %x1e in Max-Age attribute value is handled correctly.
+PASS Cookie with %x1e after Max-Age attribute value is handled correctly.
+PASS Cookie with %x1e in Expires attribute value is handled correctly.
+PASS Cookie with %x1e after Expires attribute value is handled correctly.
+PASS Cookie with %x1e in Secure attribute is handled correctly.
+PASS Cookie with %x1e after Secure attribute is handled correctly.
+PASS Cookie with %x1e in HttpOnly attribute is handled correctly.
+PASS Cookie with %x1e in SameSite attribute value is handled correctly.
+PASS Cookie with %x1e after SameSite attribute value is handled correctly.
+PASS Cookie with %x1f in Domain attribute value is handled correctly.
+PASS Cookie with %x1f after Domain attribute value is handled correctly.
+PASS Cookie with %x1f in Path attribute value is handled correctly.
+PASS Cookie with %x1f after Path attribute value is handled correctly.
+PASS Cookie with %x1f in Max-Age attribute value is handled correctly.
+PASS Cookie with %x1f after Max-Age attribute value is handled correctly.
+PASS Cookie with %x1f in Expires attribute value is handled correctly.
+PASS Cookie with %x1f after Expires attribute value is handled correctly.
+PASS Cookie with %x1f in Secure attribute is handled correctly.
+PASS Cookie with %x1f after Secure attribute is handled correctly.
+PASS Cookie with %x1f in HttpOnly attribute is handled correctly.
+PASS Cookie with %x1f in SameSite attribute value is handled correctly.
+PASS Cookie with %x1f after SameSite attribute value is handled correctly.
+PASS Cookie with %x7f in Domain attribute value is handled correctly.
+PASS Cookie with %x7f after Domain attribute value is handled correctly.
+PASS Cookie with %x7f in Path attribute value is handled correctly.
+PASS Cookie with %x7f after Path attribute value is handled correctly.
+PASS Cookie with %x7f in Max-Age attribute value is handled correctly.
+PASS Cookie with %x7f after Max-Age attribute value is handled correctly.
+PASS Cookie with %x7f in Expires attribute value is handled correctly.
+PASS Cookie with %x7f after Expires attribute value is handled correctly.
+PASS Cookie with %x7f in Secure attribute is handled correctly.
+PASS Cookie with %x7f after Secure attribute is handled correctly.
+PASS Cookie with %x7f in HttpOnly attribute is handled correctly.
+PASS Cookie with %x7f in SameSite attribute value is handled correctly.
+PASS Cookie with %x7f after SameSite attribute value is handled correctly.
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/cookies/attributes/attributes-ctl.sub.html b/third_party/blink/web_tests/external/wpt/cookies/attributes/attributes-ctl.sub.html
index 7950751..e741dfd 100644
--- a/third_party/blink/web_tests/external/wpt/cookies/attributes/attributes-ctl.sub.html
+++ b/third_party/blink/web_tests/external/wpt/cookies/attributes/attributes-ctl.sub.html
@@ -30,80 +30,65 @@
       // would not be rejected. That way, if the attribute value is ignored
       // instead of the cookie line being rejected, the test will catch it.
       for (const ctl of CTLS) {
-        // NOTE: 'expected' below is only expected in the case of the tab
-        // character. Otherwise, '' is expected.
         const controlCharacterAttributeTests = [
           {
             cookie: `test${ctl.code}domain=t; Domain=test${ctl.chr}.co; Domain=${host};`,
-            expected: `test${ctl.code}domain=t`,
             name: `Cookie with %x${ctl.code.toString(16)} in Domain attribute value is handled correctly.`,
           },
           {
             cookie: `test${ctl.code}domain2=t; Domain=${host}${ctl.chr};`,
-            expected: `test${ctl.code}domain2=t`,
             name: `Cookie with %x${ctl.code.toString(16)} after Domain attribute value is handled correctly.`,
           },
           {
             cookie: `test${ctl.code}path=t; Path=/te${ctl.chr}st; Path=${path}`,
-            expected: `test${ctl.code}path=t`,
             name: `Cookie with %x${ctl.code.toString(16)} in Path attribute value is handled correctly.`,
           },
           {
             cookie: `test${ctl.code}path2=t; Path=${path}${ctl.chr};`,
-            expected: `test${ctl.code}path2=t`,
             name: `Cookie with %x${ctl.code.toString(16)} after Path attribute value is handled correctly.`,
           },
           {
             cookie: `test${ctl.code}maxage=t; Max-Age=10${ctl.chr}00; Max-Age=1000;`,
-            expected: `test${ctl.code}maxage=t`,
             name: `Cookie with %x${ctl.code.toString(16)} in Max-Age attribute value is handled correctly.`,
           },
           {
             cookie: `test${ctl.code}maxage2=t; Max-Age=1000${ctl.chr};`,
-            expected: `test${ctl.code}maxage2=t`,
             name: `Cookie with %x${ctl.code.toString(16)} after Max-Age attribute value is handled correctly.`,
           },
           {
             cookie: `test${ctl.code}expires=t; Expires=Fri, 01 Jan 20${ctl.chr}38 00:00:00 GMT; ` +
               'Expires=Fri, 01 Jan 2038 00:00:00 GMT;',
-            expected: `test${ctl.code}expires=t`,
             name: `Cookie with %x${ctl.code.toString(16)} in Expires attribute value is handled correctly.`,
           },
           {
             cookie: `test${ctl.code}expires2=t; Expires=Fri, 01 Jan 2038 00:00:00 GMT${ctl.chr};`,
-            expected: `test${ctl.code}expires2=t`,
             name: `Cookie with %x${ctl.code.toString(16)} after Expires attribute value is handled correctly.`,
           },
           {
             cookie: `test${ctl.code}secure=t; Sec${ctl.chr}ure;`,
-            expected: `test${ctl.code}secure=t`,
             name: `Cookie with %x${ctl.code.toString(16)} in Secure attribute is handled correctly.`,
           },
           {
             cookie: `test${ctl.code}secure2=t; Secure${ctl.chr};`,
-            expected: `test${ctl.code}secure2=t`,
             name: `Cookie with %x${ctl.code.toString(16)} after Secure attribute is handled correctly.`,
           },
           {
             cookie: `test${ctl.code}httponly=t; Http${ctl.chr}Only;`,
-            expected: `test${ctl.code}httponly=t`,
             name: `Cookie with %x${ctl.code.toString(16)} in HttpOnly attribute is handled correctly.`,
           },
           {
             cookie: `test${ctl.code}samesite=t; SameSite=La${ctl.chr}x; SameSite=Lax;`,
-            expected: `test${ctl.code}samesite=t`,
             name: `Cookie with %x${ctl.code.toString(16)} in SameSite attribute value is handled correctly.`,
           },
           {
             cookie: `test${ctl.code}samesite2=t; SameSite=Lax${ctl.chr};`,
-            expected: `test${ctl.code}samesite2=t`,
             name: `Cookie with %x${ctl.code.toString(16)} after SameSite attribute value is handled correctly.`,
           },
         ];
 
         for (const test of controlCharacterAttributeTests) {
           if (ctl.code === 0x09) {
-            domCookieTest(test.cookie, test.expected, test.name);
+            domCookieTest(test.cookie, test.cookie.split(";")[0], test.name);
           } else {
             domCookieTest(test.cookie, "", test.name);
           }
diff --git a/third_party/blink/web_tests/external/wpt/cookies/name/name-ctl-expected.txt b/third_party/blink/web_tests/external/wpt/cookies/name/name-ctl-expected.txt
new file mode 100644
index 0000000..d3d31d9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/cookies/name/name-ctl-expected.txt
@@ -0,0 +1,70 @@
+This is a testharness.js-based test.
+Found 66 tests; 59 PASS, 7 FAIL, 0 TIMEOUT, 0 NOTRUN.
+FAIL Cookie with %x0 in name is rejected (DOM). assert_equals: The cookie was rejected. expected "" but got "test0"
+PASS Cookie with %x1 in name is rejected (DOM).
+PASS Cookie with %x2 in name is rejected (DOM).
+PASS Cookie with %x3 in name is rejected (DOM).
+PASS Cookie with %x4 in name is rejected (DOM).
+PASS Cookie with %x5 in name is rejected (DOM).
+PASS Cookie with %x6 in name is rejected (DOM).
+PASS Cookie with %x7 in name is rejected (DOM).
+PASS Cookie with %x8 in name is rejected (DOM).
+FAIL Cookie with %x9 in name is accepted (DOM). assert_equals: The cookie was set as expected. expected "test9\tname=9" but got ""
+FAIL Cookie with %xa in name is rejected (DOM). assert_equals: The cookie was rejected. expected "" but got "test10"
+PASS Cookie with %xb in name is rejected (DOM).
+PASS Cookie with %xc in name is rejected (DOM).
+FAIL Cookie with %xd in name is rejected (DOM). assert_equals: The cookie was rejected. expected "" but got "test13"
+PASS Cookie with %xe in name is rejected (DOM).
+PASS Cookie with %xf in name is rejected (DOM).
+PASS Cookie with %x10 in name is rejected (DOM).
+PASS Cookie with %x11 in name is rejected (DOM).
+PASS Cookie with %x12 in name is rejected (DOM).
+PASS Cookie with %x13 in name is rejected (DOM).
+PASS Cookie with %x14 in name is rejected (DOM).
+PASS Cookie with %x15 in name is rejected (DOM).
+PASS Cookie with %x16 in name is rejected (DOM).
+PASS Cookie with %x17 in name is rejected (DOM).
+PASS Cookie with %x18 in name is rejected (DOM).
+PASS Cookie with %x19 in name is rejected (DOM).
+PASS Cookie with %x1a in name is rejected (DOM).
+PASS Cookie with %x1b in name is rejected (DOM).
+PASS Cookie with %x1c in name is rejected (DOM).
+PASS Cookie with %x1d in name is rejected (DOM).
+PASS Cookie with %x1e in name is rejected (DOM).
+PASS Cookie with %x1f in name is rejected (DOM).
+PASS Cookie with %x7f in name is rejected (DOM).
+PASS Cookie with %x0 in name is rejected or modified (HTTP).
+PASS Cookie with %x1 in name is rejected (HTTP).
+PASS Cookie with %x2 in name is rejected (HTTP).
+PASS Cookie with %x3 in name is rejected (HTTP).
+PASS Cookie with %x4 in name is rejected (HTTP).
+PASS Cookie with %x5 in name is rejected (HTTP).
+PASS Cookie with %x6 in name is rejected (HTTP).
+PASS Cookie with %x7 in name is rejected (HTTP).
+PASS Cookie with %x8 in name is rejected (HTTP).
+FAIL Cookie with %x9 in name is accepted (HTTP). assert_equals: The cookie was set as expected. expected "test9\tname=9" but got ""
+FAIL Cookie with %xa in name is rejected or modified (HTTP). assert_equals: The cookie was set as expected. expected "test10 name=10" but got "test10"
+PASS Cookie with %xb in name is rejected (HTTP).
+PASS Cookie with %xc in name is rejected (HTTP).
+FAIL Cookie with %xd in name is rejected or modified (HTTP). assert_equals: The cookie was set as expected. expected "test13 name=13" but got "test13"
+PASS Cookie with %xe in name is rejected (HTTP).
+PASS Cookie with %xf in name is rejected (HTTP).
+PASS Cookie with %x10 in name is rejected (HTTP).
+PASS Cookie with %x11 in name is rejected (HTTP).
+PASS Cookie with %x12 in name is rejected (HTTP).
+PASS Cookie with %x13 in name is rejected (HTTP).
+PASS Cookie with %x14 in name is rejected (HTTP).
+PASS Cookie with %x15 in name is rejected (HTTP).
+PASS Cookie with %x16 in name is rejected (HTTP).
+PASS Cookie with %x17 in name is rejected (HTTP).
+PASS Cookie with %x18 in name is rejected (HTTP).
+PASS Cookie with %x19 in name is rejected (HTTP).
+PASS Cookie with %x1a in name is rejected (HTTP).
+PASS Cookie with %x1b in name is rejected (HTTP).
+PASS Cookie with %x1c in name is rejected (HTTP).
+PASS Cookie with %x1d in name is rejected (HTTP).
+PASS Cookie with %x1e in name is rejected (HTTP).
+PASS Cookie with %x1f in name is rejected (HTTP).
+PASS Cookie with %x7f in name is rejected (HTTP).
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/cookies/name/name-ctl.html b/third_party/blink/web_tests/external/wpt/cookies/name/name-ctl.html
index f535979..6ff2305b 100644
--- a/third_party/blink/web_tests/external/wpt/cookies/name/name-ctl.html
+++ b/third_party/blink/web_tests/external/wpt/cookies/name/name-ctl.html
@@ -25,12 +25,37 @@
           domCookieTest(
             `test${ctl.code}${ctl.chr}name=${ctl.code}`,
             `test${ctl.code}${ctl.chr}name=${ctl.code}`,
-            `Cookie with %x${ctl.code.toString(16)} in name is accepted.`);
+            `Cookie with %x${ctl.code.toString(16)} in name is accepted (DOM).`);
         } else {
           domCookieTest(
             `test${ctl.code}${ctl.chr}name=${ctl.code}`,
             '',
-            `Cookie with %x${ctl.code.toString(16)} in name is rejected.`);
+            `Cookie with %x${ctl.code.toString(16)} in name is rejected (DOM).`);
+        }
+      }
+
+      // Note that per RFC 9110, %x00, %x0A, and %x0D characters in the HTTP
+      // header MUST either cause the HTTP message to be rejected or be
+      // replaced with %x20 (space) characters. Both cases will result in a
+      // passing test here. For more info, see:
+      // https://www.rfc-editor.org/rfc/rfc9110.html#section-5.5
+      for (const ctl of CTLS) {
+        if (ctl.code === 0x09) {
+          httpCookieTest(
+            `test${ctl.code}${ctl.chr}name=${ctl.code}`,
+            `test${ctl.code}${ctl.chr}name=${ctl.code}`,
+            `Cookie with %x${ctl.code.toString(16)} in name is accepted (HTTP).`);
+        } else if (ctl.code === 0x00 || ctl.code === 0x0A || ctl.code === 0x0D) {
+          httpCookieTest(
+            `test${ctl.code}${ctl.chr}name=${ctl.code}`,
+            `test${ctl.code} name=${ctl.code}`,
+            `Cookie with %x${ctl.code.toString(16)} in name is rejected or modified (HTTP).`,
+            /* defaultPath */ true, /* allowFetchFailure */ true);
+        } else {
+          httpCookieTest(
+            `test${ctl.code}${ctl.chr}name=${ctl.code}`,
+            '',
+            `Cookie with %x${ctl.code.toString(16)} in name is rejected (HTTP).`);
         }
       }
     </script>
diff --git a/third_party/blink/web_tests/external/wpt/cookies/resources/cookie-test.js b/third_party/blink/web_tests/external/wpt/cookies/resources/cookie-test.js
index c73d4d75..a909e4d 100644
--- a/third_party/blink/web_tests/external/wpt/cookies/resources/cookie-test.js
+++ b/third_party/blink/web_tests/external/wpt/cookies/resources/cookie-test.js
@@ -49,7 +49,10 @@
 
 // httpCookieTest sets a `cookie` (via HTTP), then asserts it was or was not set
 // via `expectedValue` (via the DOM). Then cleans it up (via test driver). Most
-// tests do not set a Path attribute, so `defaultPath` defaults to true.
+// tests do not set a Path attribute, so `defaultPath` defaults to true. If the
+// cookie values are expected to cause the HTTP request or response to fail, the
+// test can be made to pass when this happens via `allowFetchFailure`, which
+// defaults to false.
 //
 // `cookie` may be a single cookie string, or an array of cookie strings, where
 // the order of the array items represents the order of the Set-Cookie headers
@@ -57,27 +60,45 @@
 //
 // Note: this function has a dependency on testdriver.js. Any test files calling
 // it should include testdriver.js and testdriver-vendor.js
-function httpCookieTest(cookie, expectedValue, name, defaultPath = true) {
-  return promise_test(async (t) => {
-    // The result is ignored as we're expiring cookies for cleaning here.
-    await getAndExpireCookiesForDefaultPathTest();
-    await test_driver.delete_all_cookies();
-    t.add_cleanup(test_driver.delete_all_cookies);
+function httpCookieTest(cookie, expectedValue, name, defaultPath = true,
+                        allowFetchFailure = false) {
+  return promise_test((t) => {
+    var skipAssertions = false;
+    return new Promise(async (resolve, reject) => {
+      // The result is ignored as we're expiring cookies for cleaning here.
+      await getAndExpireCookiesForDefaultPathTest();
+      await test_driver.delete_all_cookies();
+      t.add_cleanup(test_driver.delete_all_cookies);
 
-    let encodedCookie = encodeURIComponent(JSON.stringify(cookie));
-    await fetch(`/cookies/resources/cookie.py?set=${encodedCookie}`);
-    let cookies = document.cookie;
-    if (defaultPath) {
-      // for the tests where a Path is set from the request-uri
-      // path, we need to go look for cookies in an iframe at that
-      // default path.
-      cookies = await getAndExpireCookiesForDefaultPathTest();
-    }
-    if (Boolean(expectedValue)) {
-      assert_equals(cookies, expectedValue, 'The cookie was set as expected.');
-    } else {
-      assert_equals(cookies, expectedValue, 'The cookie was rejected.');
-    }
+      let encodedCookie = encodeURIComponent(JSON.stringify(cookie));
+      try {
+        await fetch(`/cookies/resources/cookie.py?set=${encodedCookie}`);
+      } catch {
+        if (allowFetchFailure) {
+          skipAssertions = true;
+          resolve();
+        } else {
+          reject('Failed to fetch /cookies/resources/cookie.py');
+        }
+      }
+      let cookies = document.cookie;
+      if (defaultPath) {
+        // for the tests where a Path is set from the request-uri
+        // path, we need to go look for cookies in an iframe at that
+        // default path.
+        cookies = await getAndExpireCookiesForDefaultPathTest();
+      }
+      resolve(cookies);
+    }).then((cookies) => {
+      if (skipAssertions) {
+        return;
+      }
+      if (Boolean(expectedValue)) {
+        assert_equals(cookies, expectedValue, 'The cookie was set as expected.');
+      } else {
+        assert_equals(cookies, expectedValue, 'The cookie was rejected.');
+      }
+    });
   }, name);
 }
 
diff --git a/third_party/blink/web_tests/external/wpt/cookies/value/value-ctl-expected.txt b/third_party/blink/web_tests/external/wpt/cookies/value/value-ctl-expected.txt
new file mode 100644
index 0000000..e308177
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/cookies/value/value-ctl-expected.txt
@@ -0,0 +1,70 @@
+This is a testharness.js-based test.
+Found 66 tests; 59 PASS, 7 FAIL, 0 TIMEOUT, 0 NOTRUN.
+FAIL Cookie with %x0 in value is rejected (DOM). assert_equals: The cookie was rejected. expected "" but got "test=0"
+PASS Cookie with %x1 in value is rejected (DOM).
+PASS Cookie with %x2 in value is rejected (DOM).
+PASS Cookie with %x3 in value is rejected (DOM).
+PASS Cookie with %x4 in value is rejected (DOM).
+PASS Cookie with %x5 in value is rejected (DOM).
+PASS Cookie with %x6 in value is rejected (DOM).
+PASS Cookie with %x7 in value is rejected (DOM).
+PASS Cookie with %x8 in value is rejected (DOM).
+FAIL Cookie with %x9 in value is accepted (DOM). assert_equals: The cookie was set as expected. expected "test=9\tvalue" but got ""
+FAIL Cookie with %xa in value is rejected (DOM). assert_equals: The cookie was rejected. expected "" but got "test=10"
+PASS Cookie with %xb in value is rejected (DOM).
+PASS Cookie with %xc in value is rejected (DOM).
+FAIL Cookie with %xd in value is rejected (DOM). assert_equals: The cookie was rejected. expected "" but got "test=13"
+PASS Cookie with %xe in value is rejected (DOM).
+PASS Cookie with %xf in value is rejected (DOM).
+PASS Cookie with %x10 in value is rejected (DOM).
+PASS Cookie with %x11 in value is rejected (DOM).
+PASS Cookie with %x12 in value is rejected (DOM).
+PASS Cookie with %x13 in value is rejected (DOM).
+PASS Cookie with %x14 in value is rejected (DOM).
+PASS Cookie with %x15 in value is rejected (DOM).
+PASS Cookie with %x16 in value is rejected (DOM).
+PASS Cookie with %x17 in value is rejected (DOM).
+PASS Cookie with %x18 in value is rejected (DOM).
+PASS Cookie with %x19 in value is rejected (DOM).
+PASS Cookie with %x1a in value is rejected (DOM).
+PASS Cookie with %x1b in value is rejected (DOM).
+PASS Cookie with %x1c in value is rejected (DOM).
+PASS Cookie with %x1d in value is rejected (DOM).
+PASS Cookie with %x1e in value is rejected (DOM).
+PASS Cookie with %x1f in value is rejected (DOM).
+PASS Cookie with %x7f in value is rejected (DOM).
+PASS Cookie with %x0 in name is rejected or modified (HTTP).
+PASS Cookie with %x1 in value is rejected (HTTP).
+PASS Cookie with %x2 in value is rejected (HTTP).
+PASS Cookie with %x3 in value is rejected (HTTP).
+PASS Cookie with %x4 in value is rejected (HTTP).
+PASS Cookie with %x5 in value is rejected (HTTP).
+PASS Cookie with %x6 in value is rejected (HTTP).
+PASS Cookie with %x7 in value is rejected (HTTP).
+PASS Cookie with %x8 in value is rejected (HTTP).
+FAIL Cookie with %x9 in value is accepted (HTTP). assert_equals: The cookie was set as expected. expected "test=9\tvalue" but got ""
+FAIL Cookie with %xa in name is rejected or modified (HTTP). assert_equals: The cookie was set as expected. expected "test10 name=10" but got "test10"
+PASS Cookie with %xb in value is rejected (HTTP).
+PASS Cookie with %xc in value is rejected (HTTP).
+FAIL Cookie with %xd in name is rejected or modified (HTTP). assert_equals: The cookie was set as expected. expected "test13 name=13" but got "test13"
+PASS Cookie with %xe in value is rejected (HTTP).
+PASS Cookie with %xf in value is rejected (HTTP).
+PASS Cookie with %x10 in value is rejected (HTTP).
+PASS Cookie with %x11 in value is rejected (HTTP).
+PASS Cookie with %x12 in value is rejected (HTTP).
+PASS Cookie with %x13 in value is rejected (HTTP).
+PASS Cookie with %x14 in value is rejected (HTTP).
+PASS Cookie with %x15 in value is rejected (HTTP).
+PASS Cookie with %x16 in value is rejected (HTTP).
+PASS Cookie with %x17 in value is rejected (HTTP).
+PASS Cookie with %x18 in value is rejected (HTTP).
+PASS Cookie with %x19 in value is rejected (HTTP).
+PASS Cookie with %x1a in value is rejected (HTTP).
+PASS Cookie with %x1b in value is rejected (HTTP).
+PASS Cookie with %x1c in value is rejected (HTTP).
+PASS Cookie with %x1d in value is rejected (HTTP).
+PASS Cookie with %x1e in value is rejected (HTTP).
+PASS Cookie with %x1f in value is rejected (HTTP).
+PASS Cookie with %x7f in value is rejected (HTTP).
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/cookies/value/value-ctl.html b/third_party/blink/web_tests/external/wpt/cookies/value/value-ctl.html
index eb9fee83..5a24064f 100644
--- a/third_party/blink/web_tests/external/wpt/cookies/value/value-ctl.html
+++ b/third_party/blink/web_tests/external/wpt/cookies/value/value-ctl.html
@@ -25,14 +25,40 @@
           domCookieTest(
             `test=${ctl.code}${ctl.chr}value`,
             `test=${ctl.code}${ctl.chr}value`,
-            `Cookie with %x${ctl.code.toString(16)} in value is accepted.`);
+            `Cookie with %x${ctl.code.toString(16)} in value is accepted (DOM).`);
         } else {
           domCookieTest(
             `test=${ctl.code}${ctl.chr}value`,
             '',
-            `Cookie with %x${ctl.code.toString(16)} in value is rejected.`);
+            `Cookie with %x${ctl.code.toString(16)} in value is rejected (DOM).`);
         }
       }
+
+      // Note that per RFC 9110, %x00, %x0A, and %x0D characters in the HTTP
+      // header MUST either cause the HTTP message to be rejected or be
+      // replaced with %x20 (space) characters. Both cases will result in a
+      // passing test here. For more info, see:
+      // https://www.rfc-editor.org/rfc/rfc9110.html#section-5.5
+      for (const ctl of CTLS) {
+        if (ctl.code === 0x09) {
+          httpCookieTest(
+            `test=${ctl.code}${ctl.chr}value`,
+            `test=${ctl.code}${ctl.chr}value`,
+            `Cookie with %x${ctl.code.toString(16)} in value is accepted (HTTP).`);
+        } else if (ctl.code === 0x00 || ctl.code === 0x0A || ctl.code === 0x0D) {
+          httpCookieTest(
+            `test${ctl.code}${ctl.chr}name=${ctl.code}`,
+            `test${ctl.code} name=${ctl.code}`,
+            `Cookie with %x${ctl.code.toString(16)} in name is rejected or modified (HTTP).`,
+            /* defaultPath */ true, /* allowFetchFailure */ true);
+        } else {
+          httpCookieTest(
+            `test=${ctl.code}${ctl.chr}value`,
+            '',
+            `Cookie with %x${ctl.code.toString(16)} in value is rejected (HTTP).`);
+        }
+      }
+
     </script>
   </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/borders/border-style-010.xht b/third_party/blink/web_tests/external/wpt/css/CSS2/borders/border-style-010.xht
new file mode 100644
index 0000000..d172298f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/borders/border-style-010.xht
@@ -0,0 +1,24 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+    <head>
+        <title>CSS Test: Border-style shorthand property set using a single value</title>
+        <link rel="help" href="http://www.w3.org/TR/CSS21/box.html#border-style-properties" />
+        <meta name="assert" content="The 'border-style' property set using a single value correctly renders the specified value for all sides of the element." />
+        <style type="text/css">
+            div
+            {
+                width: 153px;
+                height: 153px;
+                margin: 10px;
+                border-style: groove;
+                border-width: 20px;
+                border-color: black;
+                border-radius: 20px;
+            }
+        </style>
+    </head>
+    <body>
+        <p>Test passes if there is a box with groove borders.</p>
+        <div></div>
+    </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/animation/custom-property-transition-mismatched-inherited-property-numbers.html b/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/animation/custom-property-transition-mismatched-inherited-property-numbers.html
new file mode 100644
index 0000000..292e23b1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/animation/custom-property-transition-mismatched-inherited-property-numbers.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api-1">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/utils.js"></script>
+<div id="container"><div id="target"></div></div>
+<script>
+
+test(() => {
+    const customProperty = generate_name();
+    CSS.registerProperty({
+      name: customProperty,
+      syntax: "<number>",
+      inherits: false,
+      initialValue: "1"
+    });
+
+    // Create transitions for our custom property with
+    // a longer list of transition-duration values.
+    const container = document.getElementById("container");
+    container.style.transitionProperty = customProperty;
+    container.style.transitionDuration = "100s, 200s";
+
+    const target = document.getElementById("target");
+    target.style.transitionProperty = "inherit";
+    target.style.transitionDuration = "inherit";
+
+    // Trigger a style change by getting the custom property
+    // value from the computed style.
+    getComputedStyle(target).getPropertyValue(customProperty);
+
+    // Set a new value for the custom property, which will yield a
+    // transition.
+    target.style.setProperty(customProperty, "2");
+    const animations = target.getAnimations();
+    assert_equals(animations.length, 1, "A single transition was generated");
+
+    const transition = animations[0];
+    assert_class_string(transition, "CSSTransition", "A CSSTransition is running");
+    assert_equals(transition.transitionProperty, customProperty);
+}, 'Using a single "transition-property" value set to a custom property and two "transition-duration" values correctly yields a CSS Transition when the transition properties are set on a parent and the child inherits.');
+
+</script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-search-text-border-start-end-radius-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-search-text-border-start-end-radius-001.html.ini
new file mode 100644
index 0000000..71e3df2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-search-text-border-start-end-radius-001.html.ini
@@ -0,0 +1,2 @@
+[kind-of-widget-fallback-input-search-text-border-start-end-radius-001.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-submit-border-inline-end-width-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-submit-border-inline-end-width-001.html.ini
new file mode 100644
index 0000000..2a17062
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-submit-border-inline-end-width-001.html.ini
@@ -0,0 +1,2 @@
+[kind-of-widget-fallback-input-submit-border-inline-end-width-001.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-text-border-right-color-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-text-border-right-color-001.html.ini
new file mode 100644
index 0000000..5bc37338
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-text-border-right-color-001.html.ini
@@ -0,0 +1,2 @@
+[kind-of-widget-fallback-input-text-border-right-color-001.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-other_coop-ro_cross-origin.https.html.ini b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-other_coop-ro_cross-origin.https.html.ini
index 81a4bcf..749a9f846 100644
--- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-other_coop-ro_cross-origin.https.html.ini
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-other_coop-ro_cross-origin.https.html.ini
@@ -1,3 +1,5 @@
 [access-to-coop-page-from-other_coop-ro_cross-origin.https.html]
+  expected:
+    if processor == "x86_64": ERROR
   [access-to-coop-page-from-other (COOP-RO)]
     expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/content-type-parsing.html.ini b/third_party/blink/web_tests/external/wpt/resource-timing/content-type-parsing.html.ini
index a642e44..2eadb59 100644
--- a/third_party/blink/web_tests/external/wpt/resource-timing/content-type-parsing.html.ini
+++ b/third_party/blink/web_tests/external/wpt/resource-timing/content-type-parsing.html.ini
@@ -37,15 +37,13 @@
 
   [content-type 13 : text/plain,*/*;charset=gbk]
     expected:
-      if (os == "linux") and (flag_specific == "disable-site-isolation-trials") and (processor == "x86"): PASS
-      if os == "win": PASS
-      FAIL
+      if (os == "linux") and (flag_specific == "highdpi"): FAIL
+      if (os == "linux") and (flag_specific == ""): FAIL
 
   [content-type 14 : text/html,*/*;charset=gbk]
     expected:
-      if (os == "linux") and (flag_specific == "disable-site-isolation-trials") and (processor == "x86"): PASS
-      if os == "win": PASS
-      FAIL
+      if (os == "linux") and (flag_specific == "highdpi"): FAIL
+      if (os == "linux") and (flag_specific == ""): FAIL
 
   [content-type 15 : text/html;x=",text/plain]
     expected: FAIL
@@ -167,5 +165,8 @@
 
   [content-type 3 : text/plain;charset=gbk,text/html]
     expected:
-      if processor == "x86_64": PASS
+      if processor == "x86_64": [FAIL, PASS]
       FAIL
+
+  [content-type 2 : text/html,text/plain]
+    expected: [FAIL, PASS]
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prefetch/no-vary-search/prefetch-single.https.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prefetch/no-vary-search/prefetch-single.https.html
index 543b46c..fdbb617 100644
--- a/third_party/blink/web_tests/external/wpt/speculation-rules/prefetch/no-vary-search/prefetch-single.https.html
+++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prefetch/no-vary-search/prefetch-single.https.html
@@ -27,7 +27,11 @@
 <meta name="variant" content="?23-23">
 <meta name="variant" content="?24-24">
 <meta name="variant" content="?25-25">
-<meta name="variant" content="?26-last">
+<meta name="variant" content="?26-26">
+<meta name="variant" content="?27-27">
+<meta name="variant" content="?28-28">
+<meta name="variant" content="?29-29">
+<meta name="variant" content="?30-last">
 
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
@@ -273,6 +277,34 @@
     navigateQuery: "",
     shouldUsePrefetch: true},
 
+   {description:"Use the prefetched URL. Non-ASCII key - 2 UTF-8 code units." +
+                " Don't vary the response on the non-ASCII key.",
+    noVarySearch: 'params=("%C2%A2")',
+    prefetchQuery: "¢=3",
+    navigateQuery: "¢=4",
+    shouldUsePrefetch: true},
+
+    {description:"Use the prefetched URL. Non-ASCII key - 2 UTF-8 code units." +
+                 " Don't vary the response on the non-ASCII key.",
+    noVarySearch: 'params=("%C2%A2")',
+    prefetchQuery: "a=2&¢=3",
+    navigateQuery: "¢=4&a=2",
+    shouldUsePrefetch: true},
+
+    {description:"Don't use the prefetched URL. Non-ASCII key - 2 UTF-8 code units." +
+                 " Vary the response on the non-ASCII key.",
+    noVarySearch: 'params, except=("%C2%A2")',
+    prefetchQuery: "¢=3",
+    navigateQuery: "¢=4",
+    shouldUsePrefetch: false},
+
+    {description:"Use the prefetched URL. Non-ASCII key - 2 UTF-8 code units." +
+                 " Vary the response on the non-ASCII key.",
+    noVarySearch: 'params, except=("%C2%A2")',
+    prefetchQuery: "¢=3&a=4",
+    navigateQuery: "a=5&¢=3",
+    shouldUsePrefetch: true},
+
   ].forEach(({description, noVarySearch, prefetchQuery, navigateQuery, shouldUsePrefetch}) => {
     subsetTest(prefetch_no_vary_search_test,
       description, noVarySearch, prefetchQuery, navigateQuery,
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/embedded_style_selectors.html.ini b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/embedded_style_selectors.html.ini
new file mode 100644
index 0000000..e65e2f59
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/embedded_style_selectors.html.ini
@@ -0,0 +1,2 @@
+[embedded_style_selectors.html]
+  expected: FAIL
diff --git a/third_party/blink/web_tests/fast/borders/mixed-border-styles-radius2-expected.png b/third_party/blink/web_tests/fast/borders/mixed-border-styles-radius2-expected.png
deleted file mode 100644
index 41477c8..0000000
--- a/third_party/blink/web_tests/fast/borders/mixed-border-styles-radius2-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/fast/forms/color-scheme/select/select-multiple-appearance-basic.html b/third_party/blink/web_tests/fast/forms/color-scheme/select/select-multiple-appearance-basic.html
index 5403e031..427b75e 100644
--- a/third_party/blink/web_tests/fast/forms/color-scheme/select/select-multiple-appearance-basic.html
+++ b/third_party/blink/web_tests/fast/forms/color-scheme/select/select-multiple-appearance-basic.html
@@ -152,6 +152,15 @@
   </optgroup>
 </select><br>
 
+<!-- font -->
+<select multiple>
+  <optgroup label="font">
+    <option selected style="font-family: serif;">Selected Serif option</option>
+    <option style="font-family: monospace;">Unselected Monospace option</option>
+    <option selected style="font-family: fantasy;">Selected Fantasy option</option>
+  </optgroup>
+</select>
+
 <script>
   runAfterLayoutAndPaint(function () {
     let hoverTarget = document.getElementById('hoverTarget');
diff --git a/third_party/blink/web_tests/fast/forms/select-popup/popup-menu-different-font-indentation.html b/third_party/blink/web_tests/fast/forms/select-popup/popup-menu-different-font-indentation.html
new file mode 100644
index 0000000..43ec144
--- /dev/null
+++ b/third_party/blink/web_tests/fast/forms/select-popup/popup-menu-different-font-indentation.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<script src="../../../resources/testdriver.js"></script>
+<script src="../../../resources/testdriver-vendor.js"></script>
+<script src="../resources/picker-common.js"></script>
+
+<select>
+  <optgroup label="Standard fonts">
+    <option style="font-family: serif;">Serif</option>
+    <option selected style="font-family: sans-serif;">Sans serif</option>
+    <option style="font-family: monospace;">Monospace</option>
+  </optgroup>
+  <optgroup label="Script fonts">
+    <option style="font-family: cursive;">Cursive</option>
+    <option style="font-family: fantasy;">Fantasy</option>
+  </optgroup>
+  <option style="font-family: system-ui;">System UI</option>
+</select>
+
+<script>
+  window.onload = openPickerAppearanceOnly(document.querySelector('select'));
+</script>
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/cachestorage/oopif-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/cachestorage/oopif-expected.txt
new file mode 100644
index 0000000..1633463b
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/cachestorage/oopif-expected.txt
@@ -0,0 +1,12 @@
+Tests that OOPIF CacheStorage can also be can be accessed.
+{
+    caches : [
+        [0] : {
+            cacheId : https://devtools.oopif.test:8443/^0https://127.0.0.1^31|sw-cache-1
+            cacheName : sw-cache-1
+            securityOrigin : https://devtools.oopif.test:8443
+            storageKey : https://devtools.oopif.test:8443/^0https://127.0.0.1^31
+        }
+    ]
+}
+
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/cachestorage/oopif.js b/third_party/blink/web_tests/http/tests/inspector-protocol/cachestorage/oopif.js
new file mode 100644
index 0000000..596a259
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/cachestorage/oopif.js
@@ -0,0 +1,39 @@
+(async function(testRunner) {
+  const {page, session, dp} = await testRunner.startURL(
+      'https://127.0.0.1:8443',
+      `Tests that OOPIF CacheStorage can also be can be accessed.`);
+
+  await dp.Target.setAutoAttach({autoAttach: true, waitForDebuggerOnStart: true, flatten: true});
+  session.evaluate(`
+    const frame = document.createElement('iframe');
+    frame.src = 'https://devtools.oopif.test:8443/';
+    document.body.appendChild(frame);`);
+
+  const oopifAttached = await dp.Target.onceAttachedToTarget();
+  const oopifSession = session.createChild(oopifAttached.params.sessionId);
+  const oopifProtocol = oopifSession.protocol;
+
+  const swHelper = (await testRunner.loadScript('../service-worker/resources/service-worker-helper.js'))(oopifProtocol, oopifSession);
+  await oopifProtocol.Runtime.enable();
+  await oopifProtocol.ServiceWorker.enable();
+  await oopifProtocol.Runtime.runIfWaitingForDebugger();
+  const swActivated =
+      swHelper.installSWAndWaitForActivated('/inspector-protocol/cachestorage/resources/service-worker.js');
+
+  const swAttached = await dp.Target.onceAttachedToTarget();
+  const swProtocol = session.createChild(swAttached.params.sessionId).protocol;
+  await swProtocol.Runtime.enable();
+  await swProtocol.Runtime.runIfWaitingForDebugger();
+  await swActivated;
+
+  const oopifId =
+      (await oopifProtocol.Page.getResourceTree()).result.frameTree.frame.id;
+  const oopifStorageKey = (await oopifProtocol.Storage.getStorageKeyForFrame({
+                            frameId: oopifId
+                          })).result.storageKey;
+
+  const {result} = await oopifProtocol.CacheStorage.requestCacheNames({storageKey: oopifStorageKey});
+  testRunner.log(result);
+
+  testRunner.completeTest()
+});
diff --git a/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
index b5fb4d2..61ae5d3c 100644
--- a/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png b/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
index b0df5cb..aa55c445 100644
--- a/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
index 02c651cd..8447253 100644
--- a/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png b/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
index 3bf929c9..763734c 100644
--- a/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
+++ b/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png b/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
index c28f2e9..ed755d09 100644
--- a/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/forms/select-popup/popup-menu-appearance-minimum-font-expected.png b/third_party/blink/web_tests/platform/linux/fast/forms/select-popup/popup-menu-appearance-minimum-font-expected.png
index 46cce51..b80efade 100644
--- a/third_party/blink/web_tests/platform/linux/fast/forms/select-popup/popup-menu-appearance-minimum-font-expected.png
+++ b/third_party/blink/web_tests/platform/linux/fast/forms/select-popup/popup-menu-appearance-minimum-font-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/forms/select-popup/popup-menu-appearance-styled-expected.png b/third_party/blink/web_tests/platform/linux/fast/forms/select-popup/popup-menu-appearance-styled-expected.png
index 195f372..38deb7d 100644
--- a/third_party/blink/web_tests/platform/linux/fast/forms/select-popup/popup-menu-appearance-styled-expected.png
+++ b/third_party/blink/web_tests/platform/linux/fast/forms/select-popup/popup-menu-appearance-styled-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/forms/select-popup/popup-menu-appearance-zoom090-expected.png b/third_party/blink/web_tests/platform/linux/fast/forms/select-popup/popup-menu-appearance-zoom090-expected.png
index 5098376..c207f88 100644
--- a/third_party/blink/web_tests/platform/linux/fast/forms/select-popup/popup-menu-appearance-zoom090-expected.png
+++ b/third_party/blink/web_tests/platform/linux/fast/forms/select-popup/popup-menu-appearance-zoom090-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/forms/select-popup/popup-menu-different-font-indentation-expected.png b/third_party/blink/web_tests/platform/linux/fast/forms/select-popup/popup-menu-different-font-indentation-expected.png
new file mode 100644
index 0000000..de0c632
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/fast/forms/select-popup/popup-menu-different-font-indentation-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/forms/select/listbox-appearance-basic-expected.png b/third_party/blink/web_tests/platform/linux/fast/forms/select/listbox-appearance-basic-expected.png
index 0c99565..77b1f27 100644
--- a/third_party/blink/web_tests/platform/linux/fast/forms/select/listbox-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/linux/fast/forms/select/listbox-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/forms/select/listbox-with-display-none-option-expected.png b/third_party/blink/web_tests/platform/linux/fast/forms/select/listbox-with-display-none-option-expected.png
index 8c9b297..d26e955 100644
--- a/third_party/blink/web_tests/platform/linux/fast/forms/select/listbox-with-display-none-option-expected.png
+++ b/third_party/blink/web_tests/platform/linux/fast/forms/select/listbox-with-display-none-option-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/forms/select/optgroup-rendering-expected.png b/third_party/blink/web_tests/platform/linux/fast/forms/select/optgroup-rendering-expected.png
index 1efb870..f179610 100644
--- a/third_party/blink/web_tests/platform/linux/fast/forms/select/optgroup-rendering-expected.png
+++ b/third_party/blink/web_tests/platform/linux/fast/forms/select/optgroup-rendering-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png
index 39e6c8c..6c2acd1 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
index 8313799..fdc070d 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
index ce6542e6a..22c2ef4 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
index a05afae..07aaaf6 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
index 0bc24ac..9ca6c03 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
index 5b40779e..8035f23 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
index 9ea6706..ba4a32eed 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png b/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
index 33b5440..5034705 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
index 1343a2b..3d4e1a0c 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png b/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
index 237506b..29f21e4 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png b/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
index 67d511d..90e5dd8 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
index b5fb4d2..61ae5d3c 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png b/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
index b0df5cb..aa55c445 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
index 02c651cd..8447253 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png b/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
index 3bf929c9..763734c 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png b/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
index c28f2e9..ed755d09 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
index 3929863..a67653f 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.13/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.13/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
index a6294ee..da00da5 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.13/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.13/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
index 2c95c70..16be651 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.13/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.13/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/fast/forms/select/listbox-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/fast/forms/select/listbox-appearance-basic-expected.png
index ef281d2..32ccd9a 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.13/fast/forms/select/listbox-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.13/fast/forms/select/listbox-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
index 1bf788b..04e7c6b 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
index 3929863..a67653f 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
index a6294ee..da00da5 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
index 2c95c70..16be651 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/use-common-select-popup/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
index c2d500a8..3bd95da 100644
--- a/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
index c2d500a8..3bd95da 100644
--- a/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/html/rendering/widgets/the-select-element/select-as-listbox-default-styles.tentative-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/html/rendering/widgets/the-select-element/select-as-listbox-default-styles.tentative-expected.txt
index 20d6aef4..afcb72dc 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/html/rendering/widgets/the-select-element/select-as-listbox-default-styles.tentative-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/html/rendering/widgets/the-select-element/select-as-listbox-default-styles.tentative-expected.txt
@@ -152,7 +152,7 @@
 PASS <option>3 (in <select multiple=""><optgroup label="2">) - padding-top
 FAIL <option>3 (in <select multiple=""><optgroup label="2">) - padding-right assert_equals: expected "0px" but got "2px"
 FAIL <option>3 (in <select multiple=""><optgroup label="2">) - padding-bottom assert_equals: expected "0px" but got "1px"
-FAIL <option>3 (in <select multiple=""><optgroup label="2">) - padding-left assert_equals: expected "0px" but got "2px"
+FAIL <option>3 (in <select multiple=""><optgroup label="2">) - padding-left assert_equals: expected "0px" but got "20px"
 PASS <option>3 (in <select multiple=""><optgroup label="2">) - letter-spacing
 PASS <option>3 (in <select multiple=""><optgroup label="2">) - word-spacing
 PASS <option>3 (in <select multiple=""><optgroup label="2">) - text-transform
diff --git a/third_party/blink/web_tests/platform/mac/fast/borders/mixed-border-styles-radius2-expected.png b/third_party/blink/web_tests/platform/mac/fast/borders/mixed-border-styles-radius2-expected.png
new file mode 100644
index 0000000..c490970
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/fast/borders/mixed-border-styles-radius2-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
index b402580..e58bdf2f 100644
--- a/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
index b10376d..0b0d8db 100644
--- a/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
index 4c1153b..12a62a17f 100644
--- a/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png b/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
index 06378e10f..b20f030 100644
--- a/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
+++ b/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png b/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
index ca3ec0d..04ea5b0 100644
--- a/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/select/listbox-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac/fast/forms/select/listbox-appearance-basic-expected.png
index cf1e789..0aa04df 100644
--- a/third_party/blink/web_tests/platform/mac/fast/forms/select/listbox-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac/fast/forms/select/listbox-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/select/listbox-with-display-none-option-expected.png b/third_party/blink/web_tests/platform/mac/fast/forms/select/listbox-with-display-none-option-expected.png
index c8b1a38..c4f5570 100644
--- a/third_party/blink/web_tests/platform/mac/fast/forms/select/listbox-with-display-none-option-expected.png
+++ b/third_party/blink/web_tests/platform/mac/fast/forms/select/listbox-with-display-none-option-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/select/optgroup-rendering-expected.png b/third_party/blink/web_tests/platform/mac/fast/forms/select/optgroup-rendering-expected.png
index 2ccd442..172e143 100644
--- a/third_party/blink/web_tests/platform/mac/fast/forms/select/optgroup-rendering-expected.png
+++ b/third_party/blink/web_tests/platform/mac/fast/forms/select/optgroup-rendering-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png
index b2668c3..40b14f88 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
index 3dbed0b..630b532a 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
index a8e9f74f..81c606d 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
index 2d744ea..4a787ed 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
index 8df4a702..3b772ff 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
index 33503266..5f68ee3 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
index 347d4f0..bc1389f 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
index 1014c1eb..3bd95da 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
index 6a5cbeb..0d93534 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
index 4bd35924..deb3121 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
index e6e6284..a2b10f8 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/html/rendering/widgets/the-select-element/select-as-listbox-default-styles.tentative-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/html/rendering/widgets/the-select-element/select-as-listbox-default-styles.tentative-expected.txt
index d76850e..09e3f09c 100644
--- a/third_party/blink/web_tests/platform/win/external/wpt/html/rendering/widgets/the-select-element/select-as-listbox-default-styles.tentative-expected.txt
+++ b/third_party/blink/web_tests/platform/win/external/wpt/html/rendering/widgets/the-select-element/select-as-listbox-default-styles.tentative-expected.txt
@@ -152,7 +152,7 @@
 PASS <option>3 (in <select multiple=""><optgroup label="2">) - padding-top
 FAIL <option>3 (in <select multiple=""><optgroup label="2">) - padding-right assert_equals: expected "0px" but got "2px"
 FAIL <option>3 (in <select multiple=""><optgroup label="2">) - padding-bottom assert_equals: expected "0px" but got "1px"
-FAIL <option>3 (in <select multiple=""><optgroup label="2">) - padding-left assert_equals: expected "0px" but got "2px"
+FAIL <option>3 (in <select multiple=""><optgroup label="2">) - padding-left assert_equals: expected "0px" but got "20px"
 PASS <option>3 (in <select multiple=""><optgroup label="2">) - letter-spacing
 PASS <option>3 (in <select multiple=""><optgroup label="2">) - word-spacing
 PASS <option>3 (in <select multiple=""><optgroup label="2">) - text-transform
diff --git a/third_party/blink/web_tests/platform/win/fast/borders/mixed-border-styles-radius2-expected.png b/third_party/blink/web_tests/platform/win/fast/borders/mixed-border-styles-radius2-expected.png
index 21cbced0..5e5460f 100644
--- a/third_party/blink/web_tests/platform/win/fast/borders/mixed-border-styles-radius2-expected.png
+++ b/third_party/blink/web_tests/platform/win/fast/borders/mixed-border-styles-radius2-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
index 1f4f9799..a1f4c8a4 100644
--- a/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
index ba97da87..826fe95 100644
--- a/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
index d9fa8a5..d43cb0c4 100644
--- a/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png b/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
index 0c3add6..1e3fe49 100644
--- a/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
+++ b/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png b/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
index 452a2ab..0410df8 100644
--- a/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/forms/select-popup/popup-menu-appearance-minimum-font-expected.png b/third_party/blink/web_tests/platform/win/fast/forms/select-popup/popup-menu-appearance-minimum-font-expected.png
index f10479c..e29303a 100644
--- a/third_party/blink/web_tests/platform/win/fast/forms/select-popup/popup-menu-appearance-minimum-font-expected.png
+++ b/third_party/blink/web_tests/platform/win/fast/forms/select-popup/popup-menu-appearance-minimum-font-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/forms/select-popup/popup-menu-appearance-styled-expected.png b/third_party/blink/web_tests/platform/win/fast/forms/select-popup/popup-menu-appearance-styled-expected.png
index fbaf874..cfe996e 100644
--- a/third_party/blink/web_tests/platform/win/fast/forms/select-popup/popup-menu-appearance-styled-expected.png
+++ b/third_party/blink/web_tests/platform/win/fast/forms/select-popup/popup-menu-appearance-styled-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/forms/select-popup/popup-menu-appearance-zoom090-expected.png b/third_party/blink/web_tests/platform/win/fast/forms/select-popup/popup-menu-appearance-zoom090-expected.png
index 7de862a..3510819b 100644
--- a/third_party/blink/web_tests/platform/win/fast/forms/select-popup/popup-menu-appearance-zoom090-expected.png
+++ b/third_party/blink/web_tests/platform/win/fast/forms/select-popup/popup-menu-appearance-zoom090-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/forms/select-popup/popup-menu-different-font-indentation-expected.png b/third_party/blink/web_tests/platform/win/fast/forms/select-popup/popup-menu-different-font-indentation-expected.png
new file mode 100644
index 0000000..19cef20
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/fast/forms/select-popup/popup-menu-different-font-indentation-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/forms/select/listbox-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win/fast/forms/select/listbox-appearance-basic-expected.png
index 2439316..106ca1dc 100644
--- a/third_party/blink/web_tests/platform/win/fast/forms/select/listbox-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/win/fast/forms/select/listbox-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/forms/select/listbox-with-display-none-option-expected.png b/third_party/blink/web_tests/platform/win/fast/forms/select/listbox-with-display-none-option-expected.png
index 1d76667..a7b38080 100644
--- a/third_party/blink/web_tests/platform/win/fast/forms/select/listbox-with-display-none-option-expected.png
+++ b/third_party/blink/web_tests/platform/win/fast/forms/select/listbox-with-display-none-option-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/forms/select/optgroup-rendering-expected.png b/third_party/blink/web_tests/platform/win/fast/forms/select/optgroup-rendering-expected.png
index b7b47d80..454e3fc 100644
--- a/third_party/blink/web_tests/platform/win/fast/forms/select/optgroup-rendering-expected.png
+++ b/third_party/blink/web_tests/platform/win/fast/forms/select/optgroup-rendering-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png
index 13f221d..5e85599d 100644
--- a/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
index d7c0604..058292c 100644
--- a/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
index ab078ed..d34c7af 100644
--- a/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
index 2b3f2d1e..8d0db00 100644
--- a/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png b/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
index 55b2fb2..20d40370 100644
--- a/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png b/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
index d58fd07..888f131a 100644
--- a/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
index 5f3df3e..5301e48 100644
--- a/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
index 0390b01..4e616fa 100644
--- a/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
index 3596821..bc13f93 100644
--- a/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png b/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
index 8fc2b68..0ee58f5 100644
--- a/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png b/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
index 2281bc85..d00a993 100644
--- a/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/root-and-nested-element-transition.html.ini b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/root-and-nested-element-transition.html.ini
index 18731b1..c884b39 100644
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/root-and-nested-element-transition.html.ini
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/root-and-nested-element-transition.html.ini
@@ -1,2 +1,4 @@
 [root-and-nested-element-transition.html]
-  expected: ERROR
+  expected:
+    if processor == "x86_64": FAIL
+    ERROR
diff --git a/third_party/crashpad/crashpad/test/gtest_main.cc b/third_party/crashpad/crashpad/test/gtest_main.cc
index 605c6acc..63f13c5 100644
--- a/third_party/crashpad/crashpad/test/gtest_main.cc
+++ b/third_party/crashpad/crashpad/test/gtest_main.cc
@@ -35,7 +35,7 @@
 #endif  // BUILDFLAG(IS_WIN)
 
 #if defined(CRASHPAD_IS_IN_CHROMIUM)
-#include "base/bind.h"
+#include "base/functional/bind.h"
 #include "base/test/launcher/unit_test_launcher.h"
 #include "base/test/test_suite.h"
 #endif  // CRASHPAD_IS_IN_CHROMIUM
diff --git a/third_party/sqlite/README.chromium b/third_party/sqlite/README.chromium
index 7a79751..dadc369f 100644
--- a/third_party/sqlite/README.chromium
+++ b/third_party/sqlite/README.chromium
@@ -1,7 +1,7 @@
 Name: sqlite
 URL: https://sqlite.org/
-Version: 3.40.0
-CPEPrefix: cpe:/a:sqlite:sqlite:3.40.0
+Version: 3.40.1
+CPEPrefix: cpe:/a:sqlite:sqlite:3.40.1
 Included In Release: Yes
 Security Critical: Yes
 License: Public domain
diff --git a/tools/attribution_reporting/simulator_main.cc b/tools/attribution_reporting/simulator_main.cc
index 2f62c287..b49fd030 100644
--- a/tools/attribution_reporting/simulator_main.cc
+++ b/tools/attribution_reporting/simulator_main.cc
@@ -10,7 +10,6 @@
 #include "base/containers/contains.h"
 #include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
-#include "base/strings/abseil_string_number_conversions.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_piece.h"
 #include "base/values.h"
@@ -19,8 +18,6 @@
 #include "content/public/browser/attribution_reporting.h"
 #include "content/public/test/attribution_simulator.h"
 #include "content/public/test/attribution_simulator_environment.h"
-#include "third_party/abseil-cpp/absl/numeric/int128.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -32,7 +29,6 @@
 
 constexpr char kSwitchDelayMode[] = "delay_mode";
 constexpr char kSwitchNoiseMode[] = "noise_mode";
-constexpr char kSwitchNoiseSeed[] = "noise_seed";
 constexpr char kSwitchRemoveReportIds[] = "remove_report_ids";
 constexpr char kSwitchInputMode[] = "input_mode";
 constexpr char kSwitchCopyInputToOutput[] = "copy_input_to_output";
@@ -51,7 +47,6 @@
 
     kSwitchDelayMode,
     kSwitchNoiseMode,
-    kSwitchNoiseSeed,
     kSwitchRemoveReportIds,
     kSwitchInputMode,
     kSwitchCopyInputToOutput,
@@ -65,7 +60,6 @@
   [--copy_input_to_output]
   [--delay_mode=<mode>]
   [--noise_mode=<mode>]
-  [--noise_seed=<seed>]
   [--randomized_response_rate_event=<rate>]
   [--randomized_response_rate_navigation=<rate>]
   [--input_mode=<input_mode>]
@@ -113,15 +107,6 @@
 
                               none: None of the above applies.
 
-  --noise_seed=<seed>       - Optional 128-bit hex string. If set, the value is
-                              used to seed the random number generator used for
-                              noise; in this case, the algorithm is
-                              XorShift128+. If not set, the default source of
-                              randomness is used for noising and the
-                              simulation's output may vary between runs.
-
-                              May only be set if `noise_mode` is `noise`.
-
   --input_mode=<input_mode> - Optional. Either `single` (default) or `multi`.
                               single: the input file must conform to the JSON
                               input format below. Output will conform to the
@@ -278,24 +263,6 @@
     }
   }
 
-  absl::optional<absl::uint128> noise_seed;
-  if (command_line.HasSwitch(kSwitchNoiseSeed)) {
-    if (noise_mode != content::AttributionNoiseMode::kDefault) {
-      std::cerr << "noise seed may only be set when noise mode is `default`"
-                << std::endl;
-      return 1;
-    }
-
-    std::string str = command_line.GetSwitchValueASCII(kSwitchNoiseSeed);
-    absl::uint128 value;
-    if (!base::HexStringToUInt128(str, &value)) {
-      std::cerr << "invalid noise seed: " << str << std::endl;
-      return 1;
-    }
-
-    noise_seed = value;
-  }
-
   content::AttributionConfig config;
 
   if (!ParseRandomizedResponseRateSwitch(
@@ -342,7 +309,6 @@
 
   content::AttributionSimulationOptions options({
       .noise_mode = noise_mode,
-      .noise_seed = noise_seed,
       .config = config,
       .delay_mode = delay_mode,
       .output_options =
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index 0783f55b..99909fb4 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -28322,6 +28322,15 @@
   </description>
 </action>
 
+<action name="Settings.PrivacySandbox.Consent.MoreButtonClicked">
+  <owner>olesiamarukhno@google.com</owner>
+  <owner>sauski@google.com</owner>
+  <owner>kartoffel-core-eng@google.com</owner>
+  <description>
+    User clicked on the More button in the Privacy Sandbox Consent.
+  </description>
+</action>
+
 <action name="Settings.PrivacySandbox.Consent.Shown">
   <owner>harrisonsean@chromium.org</owner>
   <owner>sauski@google.com</owner>
@@ -28457,6 +28466,15 @@
   </description>
 </action>
 
+<action name="Settings.PrivacySandbox.Notice.MoreButtonClicked">
+  <owner>olesiamarukhno@google.com</owner>
+  <owner>sauski@google.com</owner>
+  <owner>kartoffel-core-eng@google.com</owner>
+  <description>
+    User clicked on the More button in the Privacy Sandbox Notice.
+  </description>
+</action>
+
 <action name="Settings.PrivacySandbox.Notice.OpenedSettings">
   <owner>harrisonsean@chromium.org</owner>
   <owner>sauski@google.com</owner>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index be81974..057d02b 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -41338,7 +41338,7 @@
   <int value="4007" label="CSSCascadeLayers"/>
   <int value="4008" label="CanvasRenderingContext2DConicGradient"/>
   <int value="4009" label="CanvasRenderingContext2DCanvasFilter"/>
-  <int value="4010" label="HTMLParamElementURLParameter"/>
+  <int value="4010" label="OBSOLETE_HTMLParamElementURLParameter"/>
   <int value="4011" label="V8HTMLScriptElement_Supports_Method"/>
   <int value="4012" label="HandwritingRecognitionQueryRecognizer"/>
   <int value="4013"
@@ -41441,8 +41441,8 @@
   <int value="4107" label="WebNfcNdefMakeReadOnly"/>
   <int value="4108" label="V8Navigator_DeprecatedURNToURL_Method"/>
   <int value="4109" label="OBSOLETE_WebAppManifestHandleLinks"/>
-  <int value="4110" label="HTMLParamElementURLParameterInUsePdf"/>
-  <int value="4111" label="HTMLParamElementURLParameterInUseNonPdf"/>
+  <int value="4110" label="OBSOLETE_HTMLParamElementURLParameterInUsePdf"/>
+  <int value="4111" label="OBSOLETE_HTMLParamElementURLParameterInUseNonPdf"/>
   <int value="4112" label="WebTransportServerCertificateHashes"/>
   <int value="4113" label="HiddenAttribute"/>
   <int value="4114" label="HiddenUntilFoundAttribute"/>
@@ -41791,6 +41791,9 @@
       label="DisableThirdPartySessionStoragePartitioningAfterGeneralPartitioning"/>
   <int value="4440" label="CSSPseudoHasContainsMixOfValidAndInvalid"/>
   <int value="4441" label="CSSPseudoIsWhereContainsMixOfValidAndInvalid"/>
+  <int value="4442" label="PrivateNetworkAccessFetchedSubFrame"/>
+  <int value="4443" label="PrivateNetworkAccessFetchedTopFrame"/>
+  <int value="4444" label="DisableThirdPartyStoragePartitioning"/>
 </enum>
 
 <enum name="FeaturePolicyAllowlistType">
diff --git a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
index a3b86c4..73f546f0 100644
--- a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
+++ b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
@@ -1038,11 +1038,14 @@
 </histogram_suffixes>
 
 <histogram_suffixes name="ConnectionMigrationCause" separator=".">
+  <suffix name="ChangePortOnPathDegrading" label=""/>
+  <suffix name="NewNetworkConnectedPostPathDegrading" label=""/>
   <suffix name="OnMigrateBackToDefaultNetwork" label=""/>
   <suffix name="OnNetworkConnected" label=""/>
   <suffix name="OnNetworkDisconnected" label=""/>
   <suffix name="OnNetworkMadeDefault" label=""/>
   <suffix name="OnPathDegrading" label=""/>
+  <suffix name="OnServerPreferredAddressAvailable" label=""/>
   <suffix name="OnWriteError" label=""/>
   <suffix name="Unknown" label=""/>
   <affected-histogram name="Net.QuicSession.ConnectionMigration"/>
diff --git a/tools/metrics/histograms/metadata/net/histograms.xml b/tools/metrics/histograms/metadata/net/histograms.xml
index 78512815..dbd7285 100644
--- a/tools/metrics/histograms/metadata/net/histograms.xml
+++ b/tools/metrics/histograms/metadata/net/histograms.xml
@@ -3162,6 +3162,17 @@
   </summary>
 </histogram>
 
+<histogram
+    name="Net.QuicSession.HandshakeStatusOnMigratingToServerPreferredAddress"
+    enum="BooleanConfirmed" expires_after="2024-05-11">
+  <owner>fayang@chromium.org</owner>
+  <owner>src/net/quic/OWNERS</owner>
+  <summary>
+    The handshake status when the session attempts to validate received server
+    preferred address.
+  </summary>
+</histogram>
+
 <histogram name="Net.QuicSession.HandshakeStatusOnPortMigration"
     enum="BooleanConfirmed" expires_after="2023-05-11">
   <owner>dschinazi@chromium.org</owner>
@@ -3469,6 +3480,15 @@
   </summary>
 </histogram>
 
+<histogram name="Net.QuicSession.OnServerPreferredAddressAvailable"
+    enum="QuicConnectionMigrationStatus" expires_after="2024-06-04">
+  <owner>fayang@chromium.org</owner>
+  <owner>src/net/quic/OWNERS</owner>
+  <summary>
+    The result of a QUIC server preferred address migration attempt.
+  </summary>
+</histogram>
+
 <histogram name="Net.QuicSession.OutOfOrderGapReceived" units="units"
     expires_after="2023-05-11">
   <owner>dschinazi@chromium.org</owner>
@@ -3565,7 +3585,7 @@
 </histogram>
 
 <histogram name="Net.QuicSession.PathValidationSuccess" enum="BooleanSuccess"
-    expires_after="2023-06-18">
+    expires_after="2024-06-18">
   <owner>renjietang@chromium.org</owner>
   <owner>src/net/quic/OWNERS</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/settings/histograms.xml b/tools/metrics/histograms/metadata/settings/histograms.xml
index 8bad8d3..dce0673 100644
--- a/tools/metrics/histograms/metadata/settings/histograms.xml
+++ b/tools/metrics/histograms/metadata/settings/histograms.xml
@@ -327,6 +327,18 @@
   </summary>
 </histogram>
 
+<histogram name="Settings.PrivacySandbox.DeprecatedRedirect"
+    enum="BooleanRedirected" expires_after="M115">
+  <owner>olesiamarukhno@google.com</owner>
+  <owner>sauski@google.com</owner>
+  <owner>kartoffel-core-eng@google.com</owner>
+  <summary>
+    Whether or not navigations to the Privacy sandbox settings page occured
+    because the user was redirected from the old version of the page. It occurs
+    once per navigation to the privacy sandbox settings page.
+  </summary>
+</histogram>
+
 <histogram name="Settings.PrivacySandbox.DialogDisplayHost"
     enum="SettingsPrivacySandboxDialogDisplayHostHash"
     expires_after="2023-06-18">
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml
index 674476a..a1a6735 100644
--- a/tools/metrics/ukm/ukm.xml
+++ b/tools/metrics/ukm/ukm.xml
@@ -168,7 +168,9 @@
     </summary>
     <aggregation>
       <history>
-        <statistics/>
+        <statistics>
+          <quantiles type="std-percentiles"/>
+        </statistics>
       </history>
     </aggregation>
   </metric>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 475bf11e..6c3a1b5b 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -13,8 +13,8 @@
             "full_remote_path": "perfetto-luci-artifacts/v31.0/linux-arm/trace_processor_shell"
         },
         "mac": {
-            "hash": "a6c5fcf46a921152610122c9d73ea841edd0b6d5",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/c1a1facf09f34b17247d63b72e64b0a6fbfcf048/trace_processor_shell"
+            "hash": "72c8126e9763efa4e5a35e9ec4cc67128059049b",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/db57f10ab364ee8f1a6983d1330502fee445774e/trace_processor_shell"
         },
         "mac_arm64": {
             "hash": "5f47ee79e59d00bf3889d30ca52315522c158040",
diff --git a/ui/compositor/layer.h b/ui/compositor/layer.h
index 72d396030..ac58e8cf 100644
--- a/ui/compositor/layer.h
+++ b/ui/compositor/layer.h
@@ -360,6 +360,7 @@
   const gfx::LinearGradient& gradient_mask() const {
     return cc_layer_->gradient_mask();
   }
+  bool HasGradientMask() { return !cc_layer_->gradient_mask().IsEmpty(); }
 
   // If set to true, this layer would not trigger a render surface (if possible)
   // due to having a rounded corner resulting in a better performance at the
diff --git a/ui/display/mac/screen_mac.mm b/ui/display/mac/screen_mac.mm
index 7c8fe33..2185525 100644
--- a/ui/display/mac/screen_mac.mm
+++ b/ui/display/mac/screen_mac.mm
@@ -22,7 +22,6 @@
 #include "base/mac/scoped_cftyperef.h"
 #include "base/mac/scoped_ioobject.h"
 #include "base/mac/scoped_nsobject.h"
-#include "base/mac/sdk_forward_declarations.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/timer/timer.h"
 #include "base/trace_event/trace_event.h"
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn
index 3fb3721c..f445c83 100644
--- a/ui/views/BUILD.gn
+++ b/ui/views/BUILD.gn
@@ -994,6 +994,8 @@
     "test/menu_runner_test_api.h",
     "test/menu_test_utils.cc",
     "test/menu_test_utils.h",
+    "test/mock_input_event_activation_protector.cc",
+    "test/mock_input_event_activation_protector.h",
     "test/native_widget_factory.cc",
     "test/native_widget_factory.h",
     "test/scoped_views_test_helper.cc",
@@ -1060,7 +1062,10 @@
     "//ui/gfx/geometry",
     "//ui/gl:test_support",
   ]
-  public_deps = [ "//testing/gtest" ]
+  public_deps = [
+    "//testing/gmock",
+    "//testing/gtest",
+  ]
 
   if (is_win) {
     sources += [
diff --git a/ui/views/input_event_activation_protector.h b/ui/views/input_event_activation_protector.h
index a980ca8..3cd826d 100644
--- a/ui/views/input_event_activation_protector.h
+++ b/ui/views/input_event_activation_protector.h
@@ -24,7 +24,7 @@
   InputEventActivationProtector& operator=(
       const InputEventActivationProtector&) = delete;
 
-  ~InputEventActivationProtector() = default;
+  virtual ~InputEventActivationProtector() = default;
 
   // Updates the state of the protector based off of visibility changes. This
   // method must be called when the visibility of the view is changed.
@@ -37,7 +37,7 @@
 
   // Returns true if the event is a mouse, touch, or pointer event that took
   // place within the double-click time interval after |view_shown_time_stamp_|.
-  bool IsPossiblyUnintendedInteraction(const ui::Event& event);
+  virtual bool IsPossiblyUnintendedInteraction(const ui::Event& event);
 
   // Resets the state for click tracking.
   void ResetForTesting();
diff --git a/ui/views/test/mock_input_event_activation_protector.cc b/ui/views/test/mock_input_event_activation_protector.cc
new file mode 100644
index 0000000..cd8ea1c
--- /dev/null
+++ b/ui/views/test/mock_input_event_activation_protector.cc
@@ -0,0 +1,12 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/views/test/mock_input_event_activation_protector.h"
+
+namespace views {
+MockInputEventActivationProtector::MockInputEventActivationProtector() =
+    default;
+MockInputEventActivationProtector::~MockInputEventActivationProtector() =
+    default;
+}  // namespace views
diff --git a/ui/views/test/mock_input_event_activation_protector.h b/ui/views/test/mock_input_event_activation_protector.h
new file mode 100644
index 0000000..797d650
--- /dev/null
+++ b/ui/views/test/mock_input_event_activation_protector.h
@@ -0,0 +1,37 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_VIEWS_TEST_MOCK_INPUT_EVENT_ACTIVATION_PROTECTOR_H_
+#define UI_VIEWS_TEST_MOCK_INPUT_EVENT_ACTIVATION_PROTECTOR_H_
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "ui/views/input_event_activation_protector.h"
+
+namespace views {
+
+// Mock version of InputEventActivationProtector for injection during tests, to
+// allow verifying that protected Views work as expected.
+//
+// If you are just looking to disable input protection entirely for your test,
+// use the static views::InputEventActivationProtector::DisableForTesting method
+// instead.
+class MockInputEventActivationProtector : public InputEventActivationProtector {
+ public:
+  MockInputEventActivationProtector();
+  ~MockInputEventActivationProtector() override;
+
+  MockInputEventActivationProtector(const MockInputEventActivationProtector&) =
+      delete;
+  MockInputEventActivationProtector& operator=(
+      const MockInputEventActivationProtector&) = delete;
+
+  MOCK_METHOD(bool,
+              IsPossiblyUnintendedInteraction,
+              (const ui::Event& event),
+              (override));
+};
+
+}  // namespace views
+
+#endif  // UI_VIEWS_TEST_MOCK_INPUT_EVENT_ACTIVATION_PROTECTOR_H_