diff --git a/DEPS b/DEPS
index dd60cf8..fa37d7e 100644
--- a/DEPS
+++ b/DEPS
@@ -309,11 +309,11 @@
   # 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': '2e4223a5f4bf0d20e9862ddd9c44bd0db669482a',
+  'skia_revision': 'b0c40a307d34a229b789420f5f149d734d84e47c',
   # 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': '6c11bd07c6f7e8152f4276beb5af0c241ad93d7a',
+  'v8_revision': 'ac70c755230f2856e08aa06d6fecbc3f01822758',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
@@ -336,7 +336,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Fuchsia sdk
   # and whatever else without interference from each other.
-  'fuchsia_version': 'version:12.20230413.0.1',
+  'fuchsia_version': 'version:12.20230413.2.1',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling google-toolbox-for-mac
   # and whatever else without interference from each other.
@@ -396,7 +396,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': '4054d1ec6a7211c707847713eda35c00d047cbe9',
+  'devtools_frontend_revision': 'ea48b9015d8560c423b7e3fbdc996a6fdf0f7f0a',
   # 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.
@@ -436,11 +436,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': '2200823afd79add9701ba456845763e32b4716a8',
+  'dawn_revision': 'a49353d4cd62655ecb72f4cbdb4dce7e370013ec',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'quiche_revision': '385be0b4fa0b5eb5259d6673f154554dbc316250',
+  'quiche_revision': 'e7e19a41c1475cc580bc1dccb558354261cc3ca9',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ios_webkit
   # and whatever else without interference from each other.
@@ -460,7 +460,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling nearby
   # and whatever else without interference from each other.
-  'nearby_revision': '472a1d847b581b73bb577de6a063214606d9a685',
+  'nearby_revision': 'b023a666b95f94be4f9b2070c4d0055ced78ea19',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling securemessage
   # and whatever else without interference from each other.
@@ -472,7 +472,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.
-  'cros_components_revision': '0ce149215c1ecdca92181f4a9e77d3f74c3669ad',
+  'cros_components_revision': '65e9533990a11364d8b6581ebe1255ea40e30b85',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -800,7 +800,7 @@
   },
 
   'src/docs/website': {
-    'url': Var('chromium_git') + '/website.git' + '@' + 'c61ffdadc523af5cf7d0bf68edb58c466b443a91',
+    'url': Var('chromium_git') + '/website.git' + '@' + 'f0e80c7e5b02717591271b37a222dc763b426bd2',
   },
 
   'src/ios/third_party/earl_grey2/src': {
@@ -894,7 +894,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/linux-amd64',
-          'version': 'uDGU2Ho9AnZfBoc805SH7xFdhWLLOPRhbxyF24AkdUAC',
+          'version': 'a-BAF4nZtxy5GieXXwU6QcnVvIpMbb_WEOAHnFpa644C',
         },
       ],
       'dep_type': 'cipd',
@@ -905,7 +905,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/mac-amd64',
-          'version': 'mDjfc8yVzZMzhUvuI1FMQt8zWpwmr_iZSA0P2KjotRwC',
+          'version': '7ZTAd_iLzn-5i-ZFBMaPt1fNwITxyIzW4_YWC7gScZoC',
         },
       ],
       'dep_type': 'cipd',
@@ -916,7 +916,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/windows-amd64',
-          'version': 'IhLVcXE4gfcVOfXHbRbharUD-8UZwImuHYQOoLcASS4C',
+          'version': '7mKIUu9bLXVEGqWoJ6YaUB-ahi4p-gDJmHEsV4EQkOgC',
         },
       ],
       'dep_type': 'cipd',
@@ -1187,7 +1187,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' + '@' + '9e7b29e1352dcdb45bf135a29ac5b16eb018a6a7',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '530a1bcfd20a273cc5cc0589c0b9fbd9071d7fcb',
       'condition': 'checkout_chromeos',
   },
 
@@ -1225,7 +1225,7 @@
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
 
   'src/third_party/devtools-frontend-internal': {
-      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + 'b1a213f3fa53081ef7e40ed6237e706cff33692e',
+      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '82ce0c2b01d5f959d297b0b0a5b4363b75143249',
     'condition': 'checkout_src_internal',
   },
 
@@ -1700,7 +1700,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '1c46d9577664f7cd811b4fe9c884f66a99697615',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + 'b57a685175d3070783d25958e0851b8d077b6280',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1740,7 +1740,7 @@
       'packages': [
           {
               'package': 'chromium/third_party/r8',
-              'version': 'Qs7IdwPHgKR42jCzqTBPNEMjs0uPNpDXs29NfiBcsHIC',
+              'version': 'OJEhACoTcZTFN4k6C2BsgW7xzXm818cNOV_6yhZZHwkC',
           },
       ],
       'condition': 'checkout_android',
@@ -1885,7 +1885,7 @@
     Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '0ac5d460dab4d56f3c07c43eee895557c9d3b9e4',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + 'fb8e3de0a8b9b2bba8098ed07be06115c13e904e',
+    Var('webrtc_git') + '/src.git' + '@' + 'c087d0cce50d2fa75f55e0aeb3f8f0763a80a960',
 
   # Wuffs' canonical repository is at github.com/google/wuffs, but we use
   # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file.
@@ -1975,7 +1975,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': Var('chrome_git') + '/chrome/src-internal.git@898ea6e5c95b3a47aaae29d026df0378138f4a5b',
+    'url': Var('chrome_git') + '/chrome/src-internal.git@3146ac33668eafeb7543f352648247a9f259a4a0',
     'condition': 'checkout_src_internal',
   },
 
@@ -2005,7 +2005,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/help_app/app',
-        'version': 'OQ8TTfE9eVFq9aK45B6-vVJURPnY9bNoDKVV95dTfigC',
+        'version': 'V4TW7Y9dWTSn1F8PEo5M7YQlsYWDZNgOg31yr_XkTwcC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -2016,7 +2016,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/media_app/app',
-        'version': 'tZ6xpb46Nvrf9SRtFBItPe2hnGhvPic5fASnC7Gdw7gC',
+        'version': 'TmF_BE4yuQjofhnuDyEoQ5g27UrDSbXneqBjyNNckGsC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 6c2ac729..462700ed 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -1568,6 +1568,18 @@
       False,
       []
     ),
+    BanRule(
+      r'objc/objc.h',
+      (
+        'Do not include <objc/objc.h>. It defines away ARC lifetime '
+        'annotations, and is thus dangerous.',
+        'Please use the pimpl pattern; search for `ObjCStorage` for examples.',
+        'For further reading on how to safely mix C++ and Obj-C, see',
+        'https://chromium.googlesource.com/chromium/src/+/main/docs/mac/mixing_cpp_and_objc.md'
+      ),
+      True,
+      []
+    ),
 )
 
 _BANNED_MOJOM_PATTERNS : Sequence[BanRule] = (
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn
index 5b5c4192..127e8e42 100644
--- a/android_webview/BUILD.gn
+++ b/android_webview/BUILD.gn
@@ -795,6 +795,7 @@
     "//third_party/blink/public/common:common_java",
     "//third_party/blink/renderer/platform/scheduler:blink_scheduler_java",
     "//ui/accessibility:accessibility_features_java",
+    "//ui/android:ui_android_features_java",
   ]
   srcjar_deps = [
     ":common_java_features_srcjar",
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 c9f9fff..984aa27 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
@@ -27,6 +27,7 @@
 import org.chromium.services.network.NetworkServiceFeatures;
 import org.chromium.services.tracing.TracingServiceFeatures;
 import org.chromium.ui.accessibility.AccessibilityFeatures;
+import org.chromium.ui.base.UiAndroidFeatures;
 
 /**
  * List of experimental features/flags supported for user devices. Add features/flags to this list
@@ -411,6 +412,10 @@
             Flag.baseFeature(AwFeatures.WEBVIEW_SAFE_BROWSING_SAFE_MODE,
                     "Enable doing a JNI call to check safe browsing safe mode status "
                             + "before doing a safe browsing check."),
+            Flag.baseFeature(UiAndroidFeatures.CONVERT_TRACKPAD_EVENTS_TO_MOUSE,
+                    "Enables converting trackpad click gestures to mouse events"
+                            + " in order for them to be interpreted similar to a desktop"
+                            + " experience (i.e. double-click to select word.)"),
             // Add new commandline switches and features above. The final entry should have a
             // trailing comma for cleaner diffs.
     };
diff --git a/ash/accessibility/magnifier/docked_magnifier_controller.cc b/ash/accessibility/magnifier/docked_magnifier_controller.cc
index 399621f..5f1181b 100644
--- a/ash/accessibility/magnifier/docked_magnifier_controller.cc
+++ b/ash/accessibility/magnifier/docked_magnifier_controller.cc
@@ -20,7 +20,6 @@
 #include "ash/wm/overview/overview_controller.h"
 #include "ash/wm/splitview/split_view_controller.h"
 #include "ash/wm/work_area_insets.h"
-#include "base/cxx17_backports.h"
 #include "base/functional/bind.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "components/prefs/pref_registry_simple.h"
@@ -148,7 +147,7 @@
   if (active_user_pref_service_) {
     active_user_pref_service_->SetDouble(
         prefs::kDockedMagnifierScale,
-        base::clamp(scale, kMinMagnifierScale, kMaxMagnifierScale));
+        std::clamp(scale, kMinMagnifierScale, kMaxMagnifierScale));
   }
 }
 
@@ -157,8 +156,8 @@
   if (active_user_pref_service_) {
     active_user_pref_service_->SetDouble(
         prefs::kDockedMagnifierScreenHeightDivisor,
-        base::clamp(screen_height_divisor, kMinScreenHeightDivisor,
-                    kMaxScreenHeightDivisor));
+        std::clamp(screen_height_divisor, kMinScreenHeightDivisor,
+                   kMaxScreenHeightDivisor));
   }
 }
 
@@ -468,9 +467,9 @@
     case ui::ET_MOUSE_DRAGGED:
       // User continues holding and drags separator to resize Docked Magnifier.
       if (is_resizing_) {
-        SetScreenHeightDivisor(base::clamp(new_screen_height_divisor,
-                                           kMinScreenHeightDivisor,
-                                           kMaxScreenHeightDivisor));
+        SetScreenHeightDivisor(std::clamp(new_screen_height_divisor,
+                                          kMinScreenHeightDivisor,
+                                          kMaxScreenHeightDivisor));
         OnDisplayConfigurationChanged();
       }
       break;
diff --git a/ash/accessibility/magnifier/fullscreen_magnifier_controller.cc b/ash/accessibility/magnifier/fullscreen_magnifier_controller.cc
index 4245ce21..c52d35a 100644
--- a/ash/accessibility/magnifier/fullscreen_magnifier_controller.cc
+++ b/ash/accessibility/magnifier/fullscreen_magnifier_controller.cc
@@ -19,7 +19,6 @@
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/root_window_controller.h"
 #include "ash/shell.h"
-#include "base/cxx17_backports.h"
 #include "ui/accessibility/accessibility_switches.h"
 #include "ui/aura/client/cursor_client.h"
 #include "ui/aura/window.h"
@@ -750,7 +749,7 @@
 }
 
 void FullscreenMagnifierController::ValidateScale(float* scale) {
-  *scale = base::clamp(*scale, kNonMagnifiedScale, kMaxMagnifiedScale);
+  *scale = std::clamp(*scale, kNonMagnifiedScale, kMaxMagnifiedScale);
   DCHECK(kNonMagnifiedScale <= *scale && *scale <= kMaxMagnifiedScale);
 }
 
diff --git a/ash/accessibility/magnifier/magnifier_utils.cc b/ash/accessibility/magnifier/magnifier_utils.cc
index efb62ad..4b4756c7 100644
--- a/ash/accessibility/magnifier/magnifier_utils.cc
+++ b/ash/accessibility/magnifier/magnifier_utils.cc
@@ -11,7 +11,6 @@
 #include "ash/accessibility/magnifier/fullscreen_magnifier_controller.h"
 #include "ash/shell.h"
 #include "base/check_op.h"
-#include "base/cxx17_backports.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_tree_host.h"
 #include "ui/base/ime/ash/ime_bridge.h"
@@ -57,7 +56,7 @@
   const int current_index = IndexFromScale(current_scale);
   const int new_scale_index = current_index + delta_index;
   const float new_scale = std::pow(kMagnificationScaleFactor, new_scale_index);
-  return base::clamp(new_scale, min_scale, max_scale);
+  return std::clamp(new_scale, min_scale, max_scale);
 }
 
 gfx::Rect GetViewportWidgetBoundsInRoot(aura::Window* root,
diff --git a/ash/accessibility/ui/layer_animation_info.cc b/ash/accessibility/ui/layer_animation_info.cc
index 1556da9..63d6af4 100644
--- a/ash/accessibility/ui/layer_animation_info.cc
+++ b/ash/accessibility/ui/layer_animation_info.cc
@@ -4,7 +4,7 @@
 
 #include "ash/accessibility/ui/layer_animation_info.h"
 
-#include "base/cxx17_backports.h"
+#include <algorithm>
 
 namespace ash {
 
@@ -33,7 +33,7 @@
     opacity = 1.0 - (change_delta / (fade_in_time + fade_out_time));
 
   // Layer::SetOpacity will throw an error if we're not within 0...1.
-  animation_info->opacity = base::clamp(opacity, 0.0f, 1.0f);
+  animation_info->opacity = std::clamp(opacity, 0.0f, 1.0f);
 }
 
 }  // namespace ash
diff --git a/ash/app_list/app_list_bubble_presenter.cc b/ash/app_list/app_list_bubble_presenter.cc
index eed43a99..3fb0a0df 100644
--- a/ash/app_list/app_list_bubble_presenter.cc
+++ b/ash/app_list/app_list_bubble_presenter.cc
@@ -4,6 +4,7 @@
 
 #include "ash/app_list/app_list_bubble_presenter.h"
 
+#include <algorithm>
 #include <memory>
 #include <utility>
 
@@ -27,7 +28,6 @@
 #include "ash/wm/container_finder.h"
 #include "base/check.h"
 #include "base/check_op.h"
-#include "base/cxx17_backports.h"
 #include "base/functional/bind.h"
 #include "base/i18n/rtl.h"
 #include "base/logging.h"
@@ -106,7 +106,7 @@
     int max_height =
         (work_area.height() - shelf_size - kExtraTopOfScreenSpacing) / 2;
     DCHECK_GE(max_height, default_height);
-    height = base::clamp(height_to_fit_all_apps, default_height, max_height);
+    height = std::clamp(height_to_fit_all_apps, default_height, max_height);
   }
 
   return gfx::Size(width, height);
diff --git a/ash/app_list/app_list_controller_impl.cc b/ash/app_list/app_list_controller_impl.cc
index 441635e..5b89b39 100644
--- a/ash/app_list/app_list_controller_impl.cc
+++ b/ash/app_list/app_list_controller_impl.cc
@@ -1913,10 +1913,11 @@
   return bubble_presenter_->GetPreferredBubbleWidth(root_window);
 }
 
-void AppListControllerImpl::SetHomeButtonQuickApp(const std::string& app_id) {
-  if (features::IsHomeButtonQuickAppAccessEnabled()) {
-    model_provider_->quick_app_access_model()->SetQuickApp(app_id);
+bool AppListControllerImpl::SetHomeButtonQuickApp(const std::string& app_id) {
+  if (!features::IsHomeButtonQuickAppAccessEnabled()) {
+    return false;
   }
+  return model_provider_->quick_app_access_model()->SetQuickApp(app_id);
 }
 
 }  // namespace ash
diff --git a/ash/app_list/app_list_controller_impl.h b/ash/app_list/app_list_controller_impl.h
index fd4d3d74..a4b553a 100644
--- a/ash/app_list/app_list_controller_impl.h
+++ b/ash/app_list/app_list_controller_impl.h
@@ -348,7 +348,9 @@
   // Set the launchable quick app button shown next to the home button. This app
   // icon is shown next to the home button until the app is launched or the
   // launcher is opened.
-  void SetHomeButtonQuickApp(const std::string& app_id);
+  // Returns true when the quick app was changed to a valid `app_id` or reset
+  // using an empty `app_id`.
+  bool SetHomeButtonQuickApp(const std::string& app_id);
 
  private:
   // Convenience methods for getting models from `model_provider_`.
diff --git a/ash/app_list/app_list_model_provider.h b/ash/app_list/app_list_model_provider.h
index 0e5c4c6..523c060 100644
--- a/ash/app_list/app_list_model_provider.h
+++ b/ash/app_list/app_list_model_provider.h
@@ -83,7 +83,8 @@
 
   AppListModel* model_ = &default_model_;
   SearchModel* search_model_ = &default_search_model_;
-  QuickAppAccessModel* quick_app_access_model_;
+  QuickAppAccessModel* quick_app_access_model_ =
+      &default_quick_app_access_model_;
 
   base::ObserverList<Observer> observers_;
 };
diff --git a/ash/app_list/model/app_list_item.cc b/ash/app_list/model/app_list_item.cc
index 9232dd2..58f15bf6 100644
--- a/ash/app_list/model/app_list_item.cc
+++ b/ash/app_list/model/app_list_item.cc
@@ -73,6 +73,10 @@
         observer.ItemIconChanged(config_type);
     }
   }
+
+  for (auto& observer : observers_) {
+    observer.ItemDefaultIconChanged();
+  }
 }
 
 const gfx::ImageSkia& AppListItem::GetDefaultIcon() const {
diff --git a/ash/app_list/model/app_list_item_observer.h b/ash/app_list/model/app_list_item_observer.h
index a7b2fa1..ea4767e 100644
--- a/ash/app_list/model/app_list_item_observer.h
+++ b/ash/app_list/model/app_list_item_observer.h
@@ -18,6 +18,9 @@
   // changed.
   virtual void ItemIconChanged(AppListConfigType config_type) {}
 
+  // Invoked after the item's default icon changes.
+  virtual void ItemDefaultIconChanged() {}
+
   // Invoked after item's icon version number is changed.
   virtual void ItemIconVersionChanged() {}
 
diff --git a/ash/app_list/quick_app_access_model.cc b/ash/app_list/quick_app_access_model.cc
index 52e8c0af..a9f69738 100644
--- a/ash/app_list/quick_app_access_model.cc
+++ b/ash/app_list/quick_app_access_model.cc
@@ -4,6 +4,15 @@
 
 #include "ash/app_list/quick_app_access_model.h"
 
+#include <string>
+
+#include "ash/app_list/app_list_controller_impl.h"
+#include "ash/app_list/app_list_model_provider.h"
+#include "ash/app_list/model/app_list_item.h"
+#include "ash/shell.h"
+#include "ui/gfx/image/image_skia_operations.h"
+#include "ui/gfx/image/image_skia_rep.h"
+
 namespace ash {
 
 QuickAppAccessModel::QuickAppAccessModel() = default;
@@ -18,14 +27,131 @@
   observers_.RemoveObserver(observer);
 }
 
-void QuickAppAccessModel::SetQuickApp(const std::string& app_id) {
-  quick_app_id_ = app_id;
-  for (auto& observer : observers_) {
-    // TODO(b/266734005): Check whether the app has an icon already loaded, if
-    // not, then call LoadIcon() to begin the icon loading process for the quick
-    // app. Call OnQuickAppChanged once the icon is loaded.
-    observer.OnQuickAppChanged();
+bool QuickAppAccessModel::SetQuickApp(const std::string& app_id) {
+  if (quick_app_id_ == app_id) {
+    return false;
   }
+
+  if (app_id.empty()) {
+    // Remove quick app when setting a quick app with an empty app id.
+    ClearQuickApp();
+    UpdateQuickAppShouldShowState();
+    return true;
+  }
+
+  AppListItem* item = AppListModelProvider::Get()->model()->FindItem(app_id);
+  if (!item) {
+    // Return and don't set the quick app id if the app item doesn't exist.
+    return false;
+  }
+
+  ClearQuickApp();
+  quick_app_id_ = app_id;
+  item_observation_.Observe(item);
+
+  // Request to load in the icon when the app item's icon is null.
+  if (item->GetDefaultIcon().isNull()) {
+    // TODO(b/266734005): add a histogram that tracks delay between calling
+    // LoadIcon and getting an icon loaded
+    Shell::Get()->app_list_controller()->LoadIcon(app_id);
+  }
+
+  // When quick app is already in a show state, notify that the app icon has
+  // changed to cover the case where the shown quick app is changed to another
+  // app.
+  if (quick_app_should_show_state_) {
+    for (auto& observer : observers_) {
+      observer.OnQuickAppIconChanged();
+    }
+  }
+
+  UpdateQuickAppShouldShowState();
+  return true;
+}
+
+void QuickAppAccessModel::SetQuickAppActivated() {
+  quick_app_activated_ = true;
+  UpdateQuickAppShouldShowState();
+}
+
+gfx::ImageSkia QuickAppAccessModel::GetAppIcon(gfx::Size icon_size) {
+  AppListItem* item = GetQuickAppItem();
+
+  if (!item) {
+    return gfx::ImageSkia();
+  }
+
+  gfx::ImageSkia image = item->GetDefaultIcon();
+
+  if (item->GetDefaultIcon().isNull()) {
+    return gfx::ImageSkia();
+  }
+
+  image = gfx::ImageSkiaOperations::CreateResizedImage(
+      image, skia::ImageOperations::RESIZE_BEST, icon_size);
+  return image;
+}
+
+void QuickAppAccessModel::ItemDefaultIconChanged() {
+  if (quick_app_should_show_state_) {
+    // If quick app should already be shown, notify observers when the changed
+    // icon is not null.
+    if (!GetQuickAppItem()->GetDefaultIcon().isNull()) {
+      for (auto& observer : observers_) {
+        observer.OnQuickAppIconChanged();
+      }
+    }
+  } else {
+    UpdateQuickAppShouldShowState();
+  }
+}
+
+void QuickAppAccessModel::ItemBeingDestroyed() {
+  ClearQuickApp();
+  UpdateQuickAppShouldShowState();
+}
+
+void QuickAppAccessModel::OnAppListVisibilityChanged(bool shown,
+                                                     int64_t display_id) {
+  if (shown) {
+    app_list_shown_ = true;
+    UpdateQuickAppShouldShowState();
+  }
+}
+
+AppListItem* QuickAppAccessModel::GetQuickAppItem() {
+  return AppListModelProvider::Get()->model()->FindItem(quick_app_id_);
+}
+
+void QuickAppAccessModel::UpdateQuickAppShouldShowState() {
+  const bool prev_should_show_quick_app = quick_app_should_show_state_;
+  quick_app_should_show_state_ = ShouldShowQuickApp();
+
+  if (prev_should_show_quick_app == quick_app_should_show_state_) {
+    return;
+  }
+
+  if (!quick_app_should_show_state_) {
+    app_list_controller_observer_.Reset();
+  } else {
+    app_list_controller_observer_.Observe(Shell::Get()->app_list_controller());
+  }
+
+  for (auto& observer : observers_) {
+    observer.OnQuickAppShouldShowChanged(quick_app_should_show_state_);
+  }
+}
+
+bool QuickAppAccessModel::ShouldShowQuickApp() {
+  return !quick_app_id_.empty() && !app_list_shown_ && !quick_app_activated_ &&
+         !GetQuickAppItem()->GetDefaultIcon().isNull();
+}
+
+void QuickAppAccessModel::ClearQuickApp() {
+  quick_app_id_ = "";
+  app_list_shown_ = false;
+  quick_app_activated_ = false;
+  item_observation_.Reset();
 }
 
 }  // namespace ash
diff --git a/ash/app_list/quick_app_access_model.h b/ash/app_list/quick_app_access_model.h
index b617fe4..c7b7fb7 100644
--- a/ash/app_list/quick_app_access_model.h
+++ b/ash/app_list/quick_app_access_model.h
@@ -8,42 +8,99 @@
 #include <string>
 
 #include "ash/app_list/model/app_list_item_observer.h"
+#include "ash/public/cpp/app_list/app_list_controller_observer.h"
 #include "base/observer_list.h"
+#include "base/scoped_observation.h"
+
+namespace gfx {
+class ImageSkia;
+class Size;
+}  // namespace gfx
 
 namespace ash {
 
+class AppListItem;
+class AppListController;
+
 // The model which holds information on which app is currently set as the quick
 // app. Shelf home buttons observe changes to this model and will show/hide the
 // quick app button accordingly.
-class QuickAppAccessModel {
+class QuickAppAccessModel : public AppListItemObserver,
+                            public AppListControllerObserver {
  public:
   class Observer : public base::CheckedObserver {
    public:
     ~Observer() override = default;
 
-    // Called when the currently set quick app changes.
-    virtual void OnQuickAppChanged() = 0;
+    // Called when the quick app shown state changes.
+    virtual void OnQuickAppShouldShowChanged(bool show_quick_app) = 0;
+
+    // Called when the default icon for the quick app icon changes.
+    virtual void OnQuickAppIconChanged() = 0;
   };
   QuickAppAccessModel();
 
   QuickAppAccessModel(const QuickAppAccessModel&) = delete;
   QuickAppAccessModel& operator=(const QuickAppAccessModel&) = delete;
 
-  ~QuickAppAccessModel();
+  ~QuickAppAccessModel() override;
 
   void AddObserver(Observer* observer);
   void RemoveObserver(Observer* observer);
 
-  // Set the quick app to be shown next to home buttons in the shelf.
-  void SetQuickApp(const std::string& app_id);
+  // Set the quick app what will be shown next to home buttons in the shelf.
+  // Returns true when the quick app was changed to a valid `app_id` or reset
+  // using an empty `app_id`.
+  bool SetQuickApp(const std::string& app_id);
+
+  // Set the quick app as activated and update the quick app shown state.
+  void SetQuickAppActivated();
+
+  // Returns the quick app's icon as an image, sized to 'icon_size'.
+  gfx::ImageSkia GetAppIcon(gfx::Size icon_size);
 
   const std::string& quick_app_id() { return quick_app_id_; }
+  bool quick_app_should_show_state() { return quick_app_should_show_state_; }
 
  private:
+  // AppListItemObserver:
+  void ItemDefaultIconChanged() override;
+  void ItemBeingDestroyed() override;
+
+  // AppListControllerObserver:
+  void OnAppListVisibilityChanged(bool shown, int64_t display_id) override;
+
+  AppListItem* GetQuickAppItem();
+
+  // Checks if the should show state of the quick app has changed, and notifies
+  // observers when the state does change.
+  void UpdateQuickAppShouldShowState();
+
+  // Calculates and returns whether the quick app should show.
+  bool ShouldShowQuickApp();
+
+  // Reset the quick app id and other associated variables to their default
+  // values.
+  void ClearQuickApp();
+
+  // Whether the app list has shown for the currently set quick app.
+  bool app_list_shown_ = false;
+
+  // Whether the currently set quick app has been activated.
+  bool quick_app_activated_ = false;
+
   base::ObserverList<Observer> observers_;
 
+  base::ScopedObservation<AppListItem, AppListItemObserver> item_observation_{
+      this};
+  base::ScopedObservation<AppListController, AppListControllerObserver>
+      app_list_controller_observer_{this};
+
   // The app id for the quick app.
   std::string quick_app_id_;
+
+  // Whether the quick app is in a state such that it should be shown.
+  bool quick_app_should_show_state_ = false;
 };
 
 }  // namespace ash
diff --git a/ash/app_list/test_app_list_client.cc b/ash/app_list/test_app_list_client.cc
index eb00dc8c..ddca556 100644
--- a/ash/app_list/test_app_list_client.cc
+++ b/ash/app_list/test_app_list_client.cc
@@ -101,6 +101,10 @@
 
 void TestAppListClient::OpenSearchBoxIphUrl() {}
 
+void TestAppListClient::LoadIcon(int profile_id, const std::string& app_id) {
+  loaded_icon_app_ids_.push_back(app_id);
+}
+
 std::vector<TestAppListClient::SearchResultActionId>
 TestAppListClient::GetAndResetInvokedResultActions() {
   std::vector<SearchResultActionId> result;
diff --git a/ash/app_list/test_app_list_client.h b/ash/app_list/test_app_list_client.h
index 7a2df45..36e6fc5 100644
--- a/ash/app_list/test_app_list_client.h
+++ b/ash/app_list/test_app_list_client.h
@@ -62,7 +62,7 @@
   void RecalculateWouldTriggerLauncherSearchIph() override;
   std::unique_ptr<ScopedIphSession> CreateLauncherSearchIphSession() override;
   void OpenSearchBoxIphUrl() override;
-  void LoadIcon(int profile_id, const std::string& app_id) override {}
+  void LoadIcon(int profile_id, const std::string& app_id) override;
   ash::AppListSortOrder GetPermanentSortingOrder() const override;
   void CommitTemporarySortOrder() override;
 
@@ -88,6 +88,10 @@
     return last_opened_search_result_;
   }
 
+  std::vector<std::string> load_icon_app_ids() const {
+    return loaded_icon_app_ids_;
+  }
+
   using SearchResultActionId = std::pair<std::string, int>;
   std::vector<SearchResultActionId> GetAndResetInvokedResultActions();
 
@@ -117,6 +121,7 @@
   int activate_item_count_ = 0;
   std::string activate_item_last_id_;
   std::string last_opened_search_result_;
+  std::vector<std::string> loaded_icon_app_ids_;
 
   // If not null, callback that will be run on each search request. It can be
   // used by tests to inject results to search model in response to search
diff --git a/ash/app_list/views/apps_grid_view.cc b/ash/app_list/views/apps_grid_view.cc
index 27b22645..da4a7f2 100644
--- a/ash/app_list/views/apps_grid_view.cc
+++ b/ash/app_list/views/apps_grid_view.cc
@@ -38,7 +38,6 @@
 #include "ash/public/cpp/metrics_util.h"
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/utility/haptics_util.h"
-#include "base/cxx17_backports.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
 #include "base/metrics/histogram_macros.h"
@@ -1881,7 +1880,7 @@
   int col = (point.x() - bounds.x() + x_offset -
              GetGridCenteringOffset(selected_page).x()) /
             total_tile_size.width();
-  col = base::clamp(col, 0, cols_ - 1);
+  col = std::clamp(col, 0, cols_ - 1);
 
   GridIndex max_target_index;
   if (selected_page == GetTotalPages() - 1) {
@@ -2159,7 +2158,7 @@
     cols_ = 1;
   } else {
     int preferred_cols = std::sqrt(item_list_->item_count() - 1) + 1;
-    cols_ = base::clamp(preferred_cols, 1, max_cols_);
+    cols_ = std::clamp(preferred_cols, 1, max_cols_);
   }
 
   PreferredSizeChanged();
@@ -2938,7 +2937,7 @@
   const gfx::Vector2d grid_offset = GetGridCenteringOffset(current_page);
 
   DCHECK_GT(total_tile_size.width(), 0);
-  int col = base::clamp(
+  int col = std::clamp(
       (point.x() - bounds.x() - grid_offset.x()) / total_tile_size.width(), 0,
       cols_ - 1);
 
@@ -2947,7 +2946,7 @@
       (point.y() - bounds.y() - grid_offset.y()) / total_tile_size.height();
   const absl::optional<int> tiles_per_page = TilesPerPage(current_page);
   const int row = tiles_per_page
-                      ? base::clamp(ideal_row, 0, *tiles_per_page / cols_ - 1)
+                      ? std::clamp(ideal_row, 0, *tiles_per_page / cols_ - 1)
                       : std::max(ideal_row, 0);
   return GridIndex(current_page, row * cols_ + col);
 }
diff --git a/ash/app_list/views/contents_view.cc b/ash/app_list/views/contents_view.cc
index c7add44c..d4f6013 100644
--- a/ash/app_list/views/contents_view.cc
+++ b/ash/app_list/views/contents_view.cc
@@ -20,7 +20,6 @@
 #include "ash/keyboard/ui/keyboard_ui_controller.h"
 #include "ash/public/cpp/app_list/app_list_types.h"
 #include "base/check_op.h"
-#include "base/cxx17_backports.h"
 #include "base/functional/bind.h"
 #include "base/notreached.h"
 #include "ui/compositor/layer.h"
@@ -208,7 +207,7 @@
   const int padded_width =
       GetContentsBounds().width() - 2 * AppsContainerView::kHorizontalMargin;
   return gfx::Size(
-      base::clamp(padded_width, kSearchBarMinWidth, preferred_size.width()),
+      std::clamp(padded_width, kSearchBarMinWidth, preferred_size.width()),
       preferred_size.height());
 }
 
diff --git a/ash/app_list/views/search_result_list_view.cc b/ash/app_list/views/search_result_list_view.cc
index 4a54c8c3..d79cd980 100644
--- a/ash/app_list/views/search_result_list_view.cc
+++ b/ash/app_list/views/search_result_list_view.cc
@@ -23,10 +23,13 @@
 #include "ash/public/cpp/ash_typography.h"
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/style/ash_color_id.h"
+#include "ash/style/typography.h"
 #include "base/dcheck_is_on.h"
 #include "base/time/time.h"
+#include "chromeos/constants/chromeos_features.h"
 #include "ui/accessibility/ax_node_data.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/chromeos/styles/cros_tokens_color_mappings.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/layer_animator.h"
 #include "ui/gfx/geometry/insets.h"
@@ -105,7 +108,14 @@
       u"", CONTEXT_SEARCH_RESULT_CATEGORY_LABEL, STYLE_LAUNCHER));
   title_label_->SetBackgroundColor(SK_ColorTRANSPARENT);
   title_label_->SetAutoColorReadabilityEnabled(false);
-  title_label_->SetEnabledColorId(kColorAshTextColorSecondary);
+  if (chromeos::features::IsJellyEnabled()) {
+    TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosBody2,
+                                          *title_label_);
+    title_label_->SetEnabledColorId(
+        static_cast<ui::ColorId>(cros_tokens::kCrosSysOnSurfaceVariant));
+  } else {
+    title_label_->SetEnabledColorId(kColorAshTextColorSecondary);
+  }
   title_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
   title_label_->SetBorder(views::CreateEmptyBorder(gfx::Insets::TLBR(
       kPreferredTitleTopMargins, kPreferredTitleHorizontalMargins,
diff --git a/ash/app_list/views/search_result_view.cc b/ash/app_list/views/search_result_view.cc
index 6efb2afb..60219ee 100644
--- a/ash/app_list/views/search_result_view.cc
+++ b/ash/app_list/views/search_result_view.cc
@@ -28,10 +28,13 @@
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/style/ash_color_id.h"
 #include "ash/style/ash_color_provider.h"
+#include "ash/style/typography.h"
 #include "base/functional/bind.h"
 #include "base/i18n/number_formatting.h"
+#include "chromeos/constants/chromeos_features.h"
 #include "ui/accessibility/ax_node_data.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/chromeos/styles/cros_tokens_color_mappings.h"
 #include "ui/compositor/layer.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/color_palette.h"
@@ -141,6 +144,10 @@
     case SearchResult::Tag::DIM:
       ABSL_FALLTHROUGH_INTENDED;
     case SearchResult::Tag::MATCH:
+      if (chromeos::features::IsJellyEnabled()) {
+        return is_title ? cros_tokens::kCrosSysOnSurface
+                        : cros_tokens::kCrosSysOnSurfaceVariant;
+      }
       return is_title ? kColorAshTextColorPrimary : kColorAshTextColorSecondary;
     case SearchResult::Tag::URL:
       return kColorAshTextColorURL;
@@ -198,6 +205,47 @@
           .WithOrder(flex_order));
 
   // Apply label text styling.
+  if (chromeos::features::IsJellyEnabled()) {
+    switch (label_type) {
+      case SearchResultView::LabelType::kBigTitle:
+        TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosDisplay2,
+                                              *label);
+        label->SetEnabledColorId(cros_tokens::kCrosSysOnSurface);
+        break;
+      case SearchResultView::LabelType::kBigTitleSuperscript:
+        label->SetVerticalAlignment(gfx::ALIGN_TOP);
+        TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosDisplay7,
+                                              *label);
+        label->SetEnabledColorId(cros_tokens::kCrosSysOnSurface);
+        break;
+      case SearchResultView::LabelType::kTitle:
+        TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosBody1,
+                                              *label);
+        label->SetEnabledColorId(cros_tokens::kCrosSysOnSurface);
+        break;
+      case SearchResultView::LabelType::kDetails:
+        // has_keyboard_shortcut_contents forces inline title and details text
+        // for answer cards so title and details text should use the same
+        // context.
+        if (view_type == SearchResultView::SearchResultViewType::kAnswerCard &&
+            !has_keyboard_shortcut_contents) {
+          TypographyProvider::Get()->StyleLabel(
+              TypographyToken::kCrosAnnotation1, *label);
+        } else {
+          TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosBody1,
+                                                *label);
+        }
+        label->SetEnabledColorId(cros_tokens::kCrosSysOnSurfaceVariant);
+        break;
+      case SearchResultView::LabelType::kKeyboardShortcut:
+        TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosAnnotation1,
+                                              *label);
+        label->SetEnabledColorId(cros_tokens::kCrosSysPrimary);
+        break;
+    }
+    return label;
+  }
+
   ash::AshTextContext text_context;
   switch (label_type) {
     case SearchResultView::LabelType::kBigTitle:
@@ -916,8 +964,10 @@
 
 void SearchResultView::StyleLabel(views::Label* label,
                                   const SearchResult::Tags& tags) {
-  // Reset font weight styling for label.
-  label->ApplyBaselineTextStyle();
+  if (!chromeos::features::IsJellyEnabled()) {
+    // Reset font weight styling for label.
+    label->ApplyBaselineTextStyle();
+  }
 
   for (const auto& tag : tags) {
     bool has_match_tag = (tag.styles & SearchResult::Tag::MATCH);
diff --git a/ash/clipboard/views/clipboard_history_main_button.cc b/ash/clipboard/views/clipboard_history_main_button.cc
index 2a7c815..1b21432 100644
--- a/ash/clipboard/views/clipboard_history_main_button.cc
+++ b/ash/clipboard/views/clipboard_history_main_button.cc
@@ -6,12 +6,13 @@
 
 #include "ash/clipboard/clipboard_history_util.h"
 #include "ash/clipboard/views/clipboard_history_item_view.h"
-#include "ash/constants/ash_features.h"
 #include "ash/public/cpp/style/scoped_light_mode_as_default.h"
 #include "ash/style/ash_color_id.h"
 #include "ash/style/style_util.h"
 #include "base/functional/bind.h"
+#include "chromeos/constants/chromeos_features.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
+#include "ui/chromeos/styles/cros_tokens_color_mappings.h"
 #include "ui/color/color_provider.h"
 #include "ui/gfx/canvas.h"
 #include "ui/views/accessibility/view_accessibility.h"
@@ -112,12 +113,11 @@
   // is not enabled, and light mode is the default color of NativeTheme. If
   // dark/light mode is enabled, the background color of the context menus
   // inside SystemUI will be overridden to align with current system color mode.
-  const SkColor color =
-      features::IsDarkLightModeEnabled()
-          ? GetColorProvider()->GetColor(kColorAshInkDrop)
-          : SkColorSetA(SK_ColorBLACK,
-                        StyleUtil::kLightInkDropOpacity * SK_AlphaOPAQUE);
-  flags.setColor(color);
+  const auto color_id =
+      chromeos::features::IsJellyEnabled()
+          ? static_cast<ui::ColorId>(cros_tokens::kCrosSysHoverOnSubtle)
+          : kColorAshInkDrop;
+  flags.setColor(GetColorProvider()->GetColor(color_id));
   flags.setStyle(cc::PaintFlags::kFill_Style);
   canvas->DrawRect(GetLocalBounds(), flags);
 }
diff --git a/ash/constants/ash_switches.cc b/ash/constants/ash_switches.cc
index 7d06f84..985aa3a 100644
--- a/ash/constants/ash_switches.cc
+++ b/ash/constants/ash_switches.cc
@@ -4,10 +4,10 @@
 
 #include "ash/constants/ash_switches.h"
 
+#include <algorithm>
 #include <string>
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/metrics/field_trial.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/time/time.h"
@@ -1114,8 +1114,8 @@
               kAshContextualNudgesInterval),
           &numeric_cooldown_time)) {
     base::TimeDelta cooldown_time = base::Seconds(numeric_cooldown_time);
-    cooldown_time = base::clamp(cooldown_time, kAshContextualNudgesMinInterval,
-                                kAshContextualNudgesMaxInterval);
+    cooldown_time = std::clamp(cooldown_time, kAshContextualNudgesMinInterval,
+                               kAshContextualNudgesMaxInterval);
     return absl::optional<base::TimeDelta>(cooldown_time);
   }
   return absl::nullopt;
diff --git a/ash/hud_display/cpu_graph_page_view.cc b/ash/hud_display/cpu_graph_page_view.cc
index e498eca..083260b 100644
--- a/ash/hud_display/cpu_graph_page_view.cc
+++ b/ash/hud_display/cpu_graph_page_view.cc
@@ -4,10 +4,10 @@
 
 #include "ash/hud_display/cpu_graph_page_view.h"
 
+#include <algorithm>
 #include <numeric>
 
 #include "ash/hud_display/hud_constants.h"
-#include "base/cxx17_backports.h"
 #include "base/functional/bind.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
@@ -62,7 +62,7 @@
 
   Legend::Formatter formatter = base::BindRepeating([](float value) {
     return base::ASCIIToUTF16(
-        base::StringPrintf("%d %%", base::clamp((int)(value * 100), 0, 100)));
+        base::StringPrintf("%d %%", std::clamp((int)(value * 100), 0, 100)));
   });
 
   const std::vector<Legend::Entry> legend(
diff --git a/ash/hud_display/data_source.cc b/ash/hud_display/data_source.cc
index 223b59a..dfdac978 100644
--- a/ash/hud_display/data_source.cc
+++ b/ash/hud_display/data_source.cc
@@ -7,7 +7,6 @@
 #include <algorithm>
 
 #include "ash/hud_display/memory_status.h"
-#include "base/cxx17_backports.h"
 #include "base/functional/bind.h"
 #include "base/threading/thread_restrictions.h"
 
@@ -96,7 +95,7 @@
     // Makes sure that the given value is between 0 and 1 and converts to
     // float.
     auto to_0_1 = [](const double& value) -> float {
-      return base::clamp(static_cast<float>(value), 0.0f, 1.0f);
+      return std::clamp(static_cast<float>(value), 0.0f, 1.0f);
     };
 
     snapshot.cpu_idle_part = cpu_stats_delta.idle / cpu_ticks_total;
diff --git a/ash/public/cpp/pagination/pagination_model.cc b/ash/public/cpp/pagination/pagination_model.cc
index 309dbbff..ddb6586 100644
--- a/ash/public/cpp/pagination/pagination_model.cc
+++ b/ash/public/cpp/pagination/pagination_model.cc
@@ -7,7 +7,6 @@
 #include <algorithm>
 
 #include "ash/public/cpp/pagination/pagination_model_observer.h"
-#include "base/cxx17_backports.h"
 #include "ui/gfx/animation/slide_animation.h"
 
 namespace ash {
@@ -249,7 +248,7 @@
   else if (target_page > end_page && selected_page_ == end_page)
     end_page = total_pages_;
 
-  return base::clamp(target_page, start_page, end_page);
+  return std::clamp(target_page, start_page, end_page);
 }
 
 base::TimeDelta PaginationModel::GetTransitionAnimationSlideDuration() const {
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc
index 9430f3e..29a1d1b9 100644
--- a/ash/root_window_controller.cc
+++ b/ash/root_window_controller.cc
@@ -80,7 +80,6 @@
 #include "ash/wm/workspace/workspace_layout_manager.h"
 #include "ash/wm/workspace_controller.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/functional/bind.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/ranges/algorithm.h"
@@ -413,8 +412,8 @@
   }
 
   gfx::Point FitPointToBounds(const gfx::Point p, const gfx::Rect& bounds) {
-    return gfx::Point(base::clamp(p.x(), bounds.x(), bounds.right() - 1),
-                      base::clamp(p.y(), bounds.y(), bounds.bottom() - 1));
+    return gfx::Point(std::clamp(p.x(), bounds.x(), bounds.right() - 1),
+                      std::clamp(p.y(), bounds.y(), bounds.bottom() - 1));
   }
 
   ui::EventType last_mouse_event_type_ = ui::ET_UNKNOWN;
diff --git a/ash/shelf/drag_window_from_shelf_controller.cc b/ash/shelf/drag_window_from_shelf_controller.cc
index 18f66604..e869aea5 100644
--- a/ash/shelf/drag_window_from_shelf_controller.cc
+++ b/ash/shelf/drag_window_from_shelf_controller.cc
@@ -4,6 +4,8 @@
 
 #include "ash/shelf/drag_window_from_shelf_controller.h"
 
+#include <algorithm>
+
 #include "ash/app_list/app_list_controller_impl.h"
 #include "ash/constants/ash_features.h"
 #include "ash/display/screen_orientation_controller.h"
@@ -34,7 +36,6 @@
 #include "ash/wm/window_state.h"
 #include "ash/wm/window_transient_descendant_iterator.h"
 #include "ash/wm/window_util.h"
-#include "base/cxx17_backports.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
 #include "base/metrics/histogram_macros.h"
@@ -598,8 +599,8 @@
   float y_diff = location_in_screen.y() - min_y;
   float scale = (1.0f - kMinimumWindowScaleDuringDragging) * y_diff / y_full +
                 kMinimumWindowScaleDuringDragging;
-  scale = base::clamp(scale, /*min=*/kMinimumWindowScaleDuringDragging,
-                      /*max=*/1.f);
+  scale = std::clamp(scale, /*min=*/kMinimumWindowScaleDuringDragging,
+                     /*max=*/1.f);
 
   // Calculate the desired translation so that the dragged window stays under
   // the finger during the dragging.
@@ -638,14 +639,14 @@
     float copy_scale =
         (bounds.bottom() - location_in_screen.y()) /
         (display_bounds.height() / kOtherWindowFullFadeHeightRatio);
-    copy_scale = 1.f - base::clamp(copy_scale, 0.f, 1.f);
+    copy_scale = 1.f - std::clamp(copy_scale, 0.f, 1.f);
 
     other_window_copy_->root()->SetOpacity(copy_scale);
 
     CHECK(other_window_);
     if (!WindowState::Get(other_window_)->IsFloated()) {
       const float copy_transform_scale =
-          base::clamp(copy_scale, kOtherWindowMaxScale, 1.f);
+          std::clamp(copy_scale, kOtherWindowMaxScale, 1.f);
       const gfx::Transform copy_transform = gfx::GetScaleTransform(
           other_window_copy_->root()->bounds().CenterPoint(),
           copy_transform_scale);
diff --git a/ash/shelf/home_button.cc b/ash/shelf/home_button.cc
index 2550f823..c140605 100644
--- a/ash/shelf/home_button.cc
+++ b/ash/shelf/home_button.cc
@@ -11,11 +11,13 @@
 #include "ash/app_list/app_list_model_provider.h"
 #include "ash/app_list/model/app_list_item.h"
 #include "ash/app_list/model/app_list_model.h"
+#include "ash/app_list/quick_app_access_model.h"
 #include "ash/constants/ash_features.h"
 #include "ash/public/cpp/ash_typography.h"
 #include "ash/public/cpp/shelf_config.h"
 #include "ash/public/cpp/shelf_types.h"
 #include "ash/shelf/shelf.h"
+#include "ash/shelf/shelf_control_button.h"
 #include "ash/shelf/shelf_focus_cycler.h"
 #include "ash/shelf/shelf_navigation_widget.h"
 #include "ash/shelf/shelf_view.h"
@@ -130,6 +132,8 @@
   if (features::IsHomeButtonQuickAppAccessEnabled()) {
     shell_observation_.Observe(Shell::Get());
     app_list_model_observation_.Observe(AppListModelProvider::Get());
+    quick_app_model_observation_.Observe(
+        AppListModelProvider::Get()->quick_app_access_model());
   }
 }
 
@@ -207,16 +211,11 @@
       GetDisplayId(), AppListShowSource::kShelfButton, event.time_stamp());
 
   // If the home button is pressed, fade out the nudge label if it is showing.
-  if (expandable_container_) {
+  if (expandable_container_ && !quick_app_button_) {
     // The label shouldn't be removed if the text-in-shelf feature is enabled.
     if (features::IsHomeButtonWithTextEnabled())
       return;
 
-    if (quick_app_button_) {
-      // TODO(b/266734005): Implement fade out animation for quick app button.
-      return;
-    }
-
     if (!expandable_container_->GetVisible()) {
       // If the nudge label is not visible and will not be animating, directly
       // remove them as the nudge won't be showing anymore.
@@ -494,29 +493,24 @@
 
   const int control_size = ShelfControlButton::CalculatePreferredSize().width();
 
-  SkBitmap square_icon_bitmap;
-  square_icon_bitmap.allocN32Pixels(control_size, control_size);
+  const gfx::Size preferred_size = gfx::Size(control_size, control_size);
 
-  SkCanvas canvas(square_icon_bitmap);
-  SkPaint paint_outline;
-  paint_outline.setColor(SK_ColorRED);
-  canvas.drawCircle(control_size / 2, control_size / 2, control_size / 2,
-                    paint_outline);
-
-  gfx::ImageSkia test_icon_image =
-      gfx::ImageSkia::CreateFrom1xBitmap(square_icon_bitmap);
-
-  // TODO(b/266734005): Animate in quick app once icon is loaded.
   quick_app_button_->SetPaintToLayer();
-  quick_app_button_->SetImage(views::Button::STATE_NORMAL, test_icon_image);
-  quick_app_button_->SetSize(gfx::Size(control_size, control_size));
+  quick_app_button_->layer()->SetFillsBoundsOpaquely(false);
+  quick_app_button_->SetImage(
+      views::Button::STATE_NORMAL,
+      AppListModelProvider::Get()->quick_app_access_model()->GetAppIcon(
+          preferred_size));
+  quick_app_button_->SetSize(preferred_size);
+
+  shelf_->shelf_layout_manager()->LayoutShelf(false);
 }
 
 void HomeButton::QuickAppButtonPressed() {
-  // TODO(b/266734005): Reset and hide the quick app once pressed.
   ash::Shell::Get()->app_list_controller()->ActivateItem(
-      quick_app_id_, /*event_flags=*/0,
-      ash::AppListLaunchedFrom::kLaunchedFromQuickAppAccess);
+      AppListModelProvider::Get()->quick_app_access_model()->quick_app_id(),
+      /*event_flags=*/0, ash::AppListLaunchedFrom::kLaunchedFromQuickAppAccess);
+  AppListModelProvider::Get()->quick_app_access_model()->SetQuickAppActivated();
 }
 
 void HomeButton::AnimateNudgeRipple(views::AnimationBuilder& builder) {
@@ -760,6 +754,12 @@
   nudge_label_ = nullptr;
 }
 
+void HomeButton::RemoveQuickAppButton() {
+  RemoveChildViewT(expandable_container_);
+  expandable_container_ = nullptr;
+  quick_app_button_ = nullptr;
+}
+
 bool HomeButton::DoesIntersectRect(const views::View* target,
                                    const gfx::Rect& rect) const {
   DCHECK_EQ(target, this);
@@ -794,25 +794,36 @@
 
 void HomeButton::OnActiveAppListModelsChanged(AppListModel* model,
                                               SearchModel* search_model) {
+  QuickAppAccessModel* quick_model =
+      AppListModelProvider::Get()->quick_app_access_model();
   quick_app_model_observation_.Reset();
-  quick_app_model_observation_.Observe(
-      AppListModelProvider::Get()->quick_app_access_model());
+  quick_app_model_observation_.Observe(quick_model);
 
-  OnQuickAppChanged();
+  OnQuickAppShouldShowChanged(quick_model->quick_app_should_show_state());
 }
 
-void HomeButton::OnQuickAppChanged() {
-  quick_app_id_ =
-      AppListModelProvider::Get()->quick_app_access_model()->quick_app_id();
-  if (quick_app_id_.empty()) {
-    // TODO(b/266734005): Hide the quick app button if already shown.
+void HomeButton::OnQuickAppShouldShowChanged(bool show_quick_app) {
+  if (!show_quick_app && quick_app_button_) {
+    // TODO(b/266734005): Animate the hiding of the quick app button.
+    RemoveQuickAppButton();
+  } else if (show_quick_app && !quick_app_button_) {
+    if (nudge_label_) {
+      RemoveNudgeLabel();
+    }
+    CreateQuickAppButton();
+  }
+}
+
+void HomeButton::OnQuickAppIconChanged() {
+  if (!quick_app_button_) {
     return;
   }
 
-  // Only create the quick app button if no nudge label exists already.
-  if (!quick_app_button_ && !nudge_label_) {
-    CreateQuickAppButton();
-  }
+  const int control_size = ShelfControlButton::CalculatePreferredSize().width();
+  quick_app_button_->SetImage(
+      views::Button::STATE_NORMAL,
+      AppListModelProvider::Get()->quick_app_access_model()->GetAppIcon(
+          gfx::Size(control_size, control_size)));
 }
 
 }  // namespace ash
diff --git a/ash/shelf/home_button.h b/ash/shelf/home_button.h
index 1ce809f1..2427885 100644
--- a/ash/shelf/home_button.h
+++ b/ash/shelf/home_button.h
@@ -181,6 +181,9 @@
   // Removes the nudge label from the view hierarchy.
   void RemoveNudgeLabel();
 
+  // Removes the quick app button from the view hierarchy.
+  void RemoveQuickAppButton();
+
   // views::ViewTargeterDelegate:
   bool DoesIntersectRect(const views::View* target,
                          const gfx::Rect& rect) const override;
@@ -193,7 +196,8 @@
                                     SearchModel* search_model) override;
 
   // QuickAppAccessModel::Observer:
-  void OnQuickAppChanged() override;
+  void OnQuickAppShouldShowChanged(bool quick_app_shown) override;
+  void OnQuickAppIconChanged() override;
 
   base::ScopedObservation<QuickAppAccessModel, QuickAppAccessModel::Observer>
       quick_app_model_observation_{this};
@@ -233,9 +237,6 @@
   // set by SetQuickApp().
   views::ImageButton* quick_app_button_ = nullptr;
 
-  // The app_id of the quick app button.
-  std::string quick_app_id_;
-
   base::ObserverList<NudgeAnimationObserver> observers_;
 
   base::WeakPtrFactory<HomeButton> weak_ptr_factory_{this};
diff --git a/ash/shelf/home_button_unittest.cc b/ash/shelf/home_button_unittest.cc
index 64bb5ea..e028813 100644
--- a/ash/shelf/home_button_unittest.cc
+++ b/ash/shelf/home_button_unittest.cc
@@ -29,6 +29,7 @@
 #include "ash/shelf/shelf_widget.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
+#include "ash/test/ash_test_util.h"
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
 #include "base/command_line.h"
 #include "base/run_loop.h"
@@ -37,6 +38,8 @@
 #include "ui/compositor/layer_animator.h"
 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
 #include "ui/events/test/event_generator.h"
+#include "ui/gfx/image/image.h"
+#include "ui/gfx/image/image_unittest_util.h"
 #include "ui/views/animation/bounds_animator.h"
 #include "ui/views/controls/button/image_button.h"
 #include "ui/wm/core/coordinate_conversion.h"
@@ -185,11 +188,15 @@
   base::test::ScopedFeatureList scoped_feature_list_;
 };
 
+// Test that setting an existing app item as the quick app shows a working
+// clickable quick app button.
 TEST_F(HomeButtonWithQuickAppAccess, Basic) {
   EXPECT_FALSE(IsQuickAppVisible());
 
   const std::string quick_app_id = "Quick App Item";
-  Shell::Get()->app_list_controller()->SetHomeButtonQuickApp(quick_app_id);
+  GetAppListTestHelper()->model()->CreateAndAddItem(quick_app_id);
+  EXPECT_TRUE(
+      Shell::Get()->app_list_controller()->SetHomeButtonQuickApp(quick_app_id));
 
   EXPECT_TRUE(IsQuickAppVisible());
 
@@ -204,6 +211,173 @@
   GetEventGenerator()->ClickLeftButton();
   EXPECT_EQ(1, GetTestAppListClient()->activate_item_count());
   EXPECT_EQ(quick_app_id, GetTestAppListClient()->activate_item_last_id());
+
+  // Quick app button should be hidden after clicking it.
+  EXPECT_FALSE(IsQuickAppVisible());
+}
+
+// Test that setting a quick app which is not in the app list model does not
+// show the quick app button.
+TEST_F(HomeButtonWithQuickAppAccess, NonExistentApp) {
+  EXPECT_FALSE(IsQuickAppVisible());
+  EXPECT_FALSE(Shell::Get()->app_list_controller()->SetHomeButtonQuickApp(
+      "Quick App Item"));
+  EXPECT_FALSE(IsQuickAppVisible());
+}
+
+// Test that when setting a quick app with no icon, the quick app button doesn't
+// show until an icon is loaded.
+TEST_F(HomeButtonWithQuickAppAccess, AppWithNoIconThenLoaded) {
+  EXPECT_FALSE(IsQuickAppVisible());
+
+  const std::string quick_app_id = "Quick App Item";
+  AppListItem* item = new AppListItem(quick_app_id);
+  GetAppListTestHelper()->model()->AddItem(item);
+
+  EXPECT_TRUE(Shell::Get()->app_list_controller()->SetHomeButtonQuickApp(
+      "Quick App Item"));
+
+  // Check that the quick app item with no icon is not visible, and that icon
+  // load was requested.
+  EXPECT_FALSE(IsQuickAppVisible());
+  EXPECT_EQ(std::vector<std::string>{quick_app_id},
+            GetTestAppListClient()->load_icon_app_ids());
+
+  // Set the default icon and check that the quick app button is visible after.
+  item->SetDefaultIconAndColor(
+      CreateSolidColorTestImage(gfx::Size(32, 32), SK_ColorRED), IconColor());
+  EXPECT_TRUE(IsQuickAppVisible());
+}
+
+// Test that the quick app button image changes when setting a new quick app
+// with a quick app button already shown.
+TEST_F(HomeButtonWithQuickAppAccess, IconUpdatesOnNewQuickAppSet) {
+  EXPECT_FALSE(IsQuickAppVisible());
+
+  const std::string quick_app_id = "Quick App Item";
+  AppListItem* item = new AppListItem(quick_app_id);
+  GetAppListTestHelper()->model()->AddItem(item);
+  item->SetDefaultIconAndColor(
+      CreateSolidColorTestImage(gfx::Size(32, 32), SK_ColorRED), IconColor());
+
+  const std::string quick_app_id_two = "Quick App Item Two";
+  AppListItem* item_two = new AppListItem(quick_app_id_two);
+  GetAppListTestHelper()->model()->AddItem(item_two);
+  item_two->SetDefaultIconAndColor(
+      CreateSolidColorTestImage(gfx::Size(32, 32), SK_ColorBLUE), IconColor());
+
+  EXPECT_TRUE(
+      Shell::Get()->app_list_controller()->SetHomeButtonQuickApp(quick_app_id));
+  EXPECT_TRUE(IsQuickAppVisible());
+
+  gfx::ImageSkia image_one =
+      home_button()->quick_app_button_for_test()->GetImage(
+          views::Button::STATE_NORMAL);
+
+  EXPECT_TRUE(Shell::Get()->app_list_controller()->SetHomeButtonQuickApp(
+      quick_app_id_two));
+  EXPECT_TRUE(IsQuickAppVisible());
+
+  gfx::ImageSkia image_two =
+      home_button()->quick_app_button_for_test()->GetImage(
+          views::Button::STATE_NORMAL);
+
+  // Check that the quick app button image is changed after setting a new quick
+  // app.
+  EXPECT_FALSE(
+      gfx::test::AreImagesEqual(gfx::Image(image_one), gfx::Image(image_two)));
+}
+
+// Test that the quick app button is hidden when the home button is pressed.
+TEST_F(HomeButtonWithQuickAppAccess, HomeButtonPressed) {
+  EXPECT_FALSE(IsQuickAppVisible());
+
+  const std::string quick_app_id = "Quick App Item";
+  GetAppListTestHelper()->model()->CreateAndAddItem(quick_app_id);
+  EXPECT_TRUE(
+      Shell::Get()->app_list_controller()->SetHomeButtonQuickApp(quick_app_id));
+
+  EXPECT_TRUE(IsQuickAppVisible());
+
+  gfx::Point center = home_button()->GetBoundsInScreen().CenterPoint();
+  GetEventGenerator()->MoveMouseTo(center);
+  GetEventGenerator()->ClickLeftButton();
+
+  EXPECT_FALSE(IsQuickAppVisible());
+}
+
+// Test that the quick app button is hidden when the app list is opened.
+TEST_F(HomeButtonWithQuickAppAccess, AppListOpened) {
+  EXPECT_FALSE(IsQuickAppVisible());
+
+  const std::string quick_app_id = "Quick App Item";
+  GetAppListTestHelper()->model()->CreateAndAddItem(quick_app_id);
+  EXPECT_TRUE(
+      Shell::Get()->app_list_controller()->SetHomeButtonQuickApp(quick_app_id));
+
+  EXPECT_TRUE(IsQuickAppVisible());
+
+  GetAppListTestHelper()->ShowAppList();
+
+  EXPECT_FALSE(IsQuickAppVisible());
+}
+
+// Test that the quick app button on both displays get shown and hidden
+// together.
+TEST_F(HomeButtonWithQuickAppAccess, TwoDisplays) {
+  UpdateDisplay("10+10-500x400,600+10-1000x600/r");
+
+  HomeButton* second_home_button =
+      Shelf::ForWindow(Shell::GetAllRootWindows()[1])
+          ->shelf_widget()
+          ->navigation_widget()
+          ->GetHomeButton();
+
+  EXPECT_NE(home_button(), second_home_button);
+  EXPECT_FALSE(second_home_button->quick_app_button_for_test());
+  EXPECT_FALSE(home_button()->quick_app_button_for_test());
+
+  // Set the quick app and ensure the quick app button is shown on both
+  // displays.
+  const std::string quick_app_id = "Quick App Item";
+  GetAppListTestHelper()->model()->CreateAndAddItem(quick_app_id);
+  EXPECT_TRUE(
+      Shell::Get()->app_list_controller()->SetHomeButtonQuickApp(quick_app_id));
+
+  EXPECT_TRUE(second_home_button->quick_app_button_for_test());
+  EXPECT_TRUE(home_button()->quick_app_button_for_test());
+
+  // Click the home button on the first display.
+  gfx::Point center = home_button()->GetBoundsInScreen().CenterPoint();
+  GetEventGenerator()->MoveMouseTo(center);
+  GetEventGenerator()->ClickLeftButton();
+
+  // Both quick app buttons should be hidden.
+  EXPECT_FALSE(second_home_button->quick_app_button_for_test());
+  EXPECT_FALSE(home_button()->quick_app_button_for_test());
+}
+
+// Test that setting an empty string as the quick app id hides the existing
+// quick app button.
+TEST_F(HomeButtonWithQuickAppAccess, EmptyAppId) {
+  EXPECT_FALSE(IsQuickAppVisible());
+
+  const std::string quick_app_id = "Quick App Item";
+  GetAppListTestHelper()->model()->CreateAndAddItem(quick_app_id);
+
+  // Setting the quick app to emtpy app id initially does not show the quick app
+  // button.
+  EXPECT_FALSE(Shell::Get()->app_list_controller()->SetHomeButtonQuickApp(""));
+  EXPECT_FALSE(IsQuickAppVisible());
+
+  // Set quick app id shows the quick app button.
+  EXPECT_TRUE(
+      Shell::Get()->app_list_controller()->SetHomeButtonQuickApp(quick_app_id));
+  EXPECT_TRUE(IsQuickAppVisible());
+
+  // Setting to an empty app id hides the quick app button.
+  EXPECT_TRUE(Shell::Get()->app_list_controller()->SetHomeButtonQuickApp(""));
+  EXPECT_FALSE(IsQuickAppVisible());
 }
 
 enum class TestAccessibilityFeature {
diff --git a/ash/shelf/scrollable_shelf_view.cc b/ash/shelf/scrollable_shelf_view.cc
index f80dcc7..2a65c55 100644
--- a/ash/shelf/scrollable_shelf_view.cc
+++ b/ash/shelf/scrollable_shelf_view.cc
@@ -19,7 +19,6 @@
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/system/status_area_widget.h"
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
-#include "base/cxx17_backports.h"
 #include "base/functional/bind.h"
 #include "base/i18n/rtl.h"
 #include "base/metrics/histogram_functions.h"
@@ -621,7 +620,7 @@
     int available_space_for_icons) const {
   const float scroll_upper_bound =
       CalculateScrollUpperBound(available_space_for_icons);
-  scroll = base::clamp(scroll, 0.0f, scroll_upper_bound);
+  scroll = std::clamp(scroll, 0.0f, scroll_upper_bound);
   return scroll;
 }
 
@@ -1829,11 +1828,11 @@
   // TODO(b/268401797): Rewrite CalculateTappableIconIndices() as a more
   // thorough fix for out of bound indices.
   first_visible_view_index =
-      base::clamp(first_visible_view_index, static_cast<size_t>(0),
-                  visible_views_indices.size() - 1);
+      std::clamp(first_visible_view_index, static_cast<size_t>(0),
+                 visible_views_indices.size() - 1);
   last_visible_view_index =
-      base::clamp(last_visible_view_index, first_visible_view_index,
-                  visible_views_indices.size() - 1);
+      std::clamp(last_visible_view_index, first_visible_view_index,
+                 visible_views_indices.size() - 1);
 
   return {visible_views_indices[first_visible_view_index],
           visible_views_indices[last_visible_view_index]};
diff --git a/ash/shelf/shelf_view.cc b/ash/shelf/shelf_view.cc
index 5823e4d..d895991 100644
--- a/ash/shelf/shelf_view.cc
+++ b/ash/shelf/shelf_view.cc
@@ -4,6 +4,7 @@
 
 #include "ash/shelf/shelf_view.h"
 
+#include <algorithm>
 #include <memory>
 #include <utility>
 
@@ -52,7 +53,6 @@
 #include "base/check_op.h"
 #include "base/containers/adapters.h"
 #include "base/containers/contains.h"
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
@@ -1701,7 +1701,7 @@
   size_t target_index = views::ViewModelUtils::DetermineMoveIndex(
       *view_model_, drag_view_, shelf_->IsHorizontalAlignment(),
       drag_view_->x(), drag_view_->y());
-  target_index = base::clamp(target_index, indices.first, indices.second);
+  target_index = std::clamp(target_index, indices.first, indices.second);
 
   // Check the relative position of |drag_view_| and its ideal bounds if it can
   // be dragged across the separator to pin.
diff --git a/ash/shelf/swipe_home_to_overview_controller.cc b/ash/shelf/swipe_home_to_overview_controller.cc
index d756c1df..60514455 100644
--- a/ash/shelf/swipe_home_to_overview_controller.cc
+++ b/ash/shelf/swipe_home_to_overview_controller.cc
@@ -4,6 +4,8 @@
 
 #include "ash/shelf/swipe_home_to_overview_controller.h"
 
+#include <algorithm>
+
 #include "ash/app_list/app_list_controller_impl.h"
 #include "ash/constants/ash_features.h"
 #include "ash/controls/contextual_tooltip.h"
@@ -15,7 +17,6 @@
 #include "ash/shell.h"
 #include "ash/wm/overview/overview_controller.h"
 #include "ash/wm/overview/overview_session.h"
-#include "base/cxx17_backports.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
 #include "base/metrics/histogram_macros.h"
@@ -128,7 +129,7 @@
 
   const float progress = gfx::Tween::CalculateValue(
       gfx::Tween::FAST_OUT_SLOW_IN,
-      base::clamp(1.f - distance / target_distance, 0.0f, 1.0f));
+      std::clamp(1.f - distance / target_distance, 0.0f, 1.0f));
 
   float scale = gfx::Tween::FloatValueBetween(progress, 1.0f, kTargetHomeScale);
   Shell::Get()->app_list_controller()->UpdateScaleAndOpacityForHomeLauncher(
diff --git a/ash/style/color_util.cc b/ash/style/color_util.cc
index e79e2d6..9bbd3a3 100644
--- a/ash/style/color_util.cc
+++ b/ash/style/color_util.cc
@@ -4,11 +4,12 @@
 
 #include "ash/style/color_util.h"
 
+#include <algorithm>
+
 #include "ash/public/cpp/wallpaper/wallpaper_types.h"
 #include "ash/root_window_controller.h"
 #include "ash/shell.h"
 #include "ash/wallpaper/wallpaper_controller_impl.h"
-#include "base/cxx17_backports.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/gfx/color_utils.h"
@@ -66,9 +67,9 @@
   color_utils::SkColorToHSL(color, &hsl);
 
   if (use_dark_color) {
-    hsl.l = base::clamp(hsl.l, kMinLightnessDarkMode, 1.0);
+    hsl.l = std::clamp(hsl.l, kMinLightnessDarkMode, 1.0);
   } else {
-    hsl.l = base::clamp(hsl.l, 0.0, kMaxLightnessLightMode);
+    hsl.l = std::clamp(hsl.l, 0.0, kMaxLightnessLightMode);
   }
   return color_utils::HSLToSkColor(hsl, SkColorGetA(color));
 }
diff --git a/ash/system/camera/autozoom_toast_controller.cc b/ash/system/camera/autozoom_toast_controller.cc
index 070e734..cb621c3 100644
--- a/ash/system/camera/autozoom_toast_controller.cc
+++ b/ash/system/camera/autozoom_toast_controller.cc
@@ -4,6 +4,8 @@
 
 #include "ash/system/camera/autozoom_toast_controller.h"
 
+#include <algorithm>
+
 #include "ash/accessibility/accessibility_controller_impl.h"
 #include "ash/shelf/shelf.h"
 #include "ash/shell.h"
@@ -11,7 +13,6 @@
 #include "ash/system/tray/tray_constants.h"
 #include "ash/system/tray/tray_utils.h"
 #include "ash/system/unified/unified_system_tray.h"
-#include "base/cxx17_backports.h"
 
 namespace ash {
 
@@ -149,8 +150,8 @@
 void AutozoomToastController::UpdateToastView() {
   if (toast_view_) {
     toast_view_->SetAutozoomEnabled(/*enabled=*/delegate_->IsAutozoomEnabled());
-    int width = base::clamp(toast_view_->GetPreferredSize().width(),
-                            kAutozoomToastMinWidth, kAutozoomToastMaxWidth);
+    int width = std::clamp(toast_view_->GetPreferredSize().width(),
+                           kAutozoomToastMinWidth, kAutozoomToastMaxWidth);
     bubble_view_->SetPreferredWidth(width);
   }
 }
diff --git a/ash/system/message_center/message_center_scroll_bar.cc b/ash/system/message_center/message_center_scroll_bar.cc
index d7b616e..f410b90 100644
--- a/ash/system/message_center/message_center_scroll_bar.cc
+++ b/ash/system/message_center/message_center_scroll_bar.cc
@@ -10,6 +10,7 @@
 #include "ui/base/metadata/metadata_impl_macros.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/presentation_time_recorder.h"
+#include "ui/views/controls/scrollbar/base_scroll_bar_thumb.h"
 #include "ui/views/widget/widget.h"
 
 namespace {
@@ -44,90 +45,7 @@
 BEGIN_METADATA(RoundedMessageCenterScrollBar, RoundedScrollBar)
 END_METADATA
 
-MessageCenterScrollBar::MessageCenterScrollBar(
-    MessageCenterScrollBar::Observer* observer)
-    : views::OverlayScrollBar(false), observer_(observer) {
-  GetThumb()->layer()->SetVisible(features::IsNotificationScrollBarEnabled());
-  GetThumb()->layer()->CompleteAllAnimations();
-}
-
-MessageCenterScrollBar::~MessageCenterScrollBar() = default;
-
-bool MessageCenterScrollBar::OnKeyPressed(const ui::KeyEvent& event) {
-  if (!stats_recorded_ &&
-      (event.key_code() == ui::VKEY_UP || event.key_code() == ui::VKEY_DOWN)) {
-    CollectScrollActionReason(ScrollActionReason::kByArrowKey);
-    stats_recorded_ = true;
-  }
-  return views::OverlayScrollBar::OnKeyPressed(event);
-}
-
-bool MessageCenterScrollBar::OnMouseWheel(const ui::MouseWheelEvent& event) {
-  if (!stats_recorded_) {
-    CollectScrollActionReason(ScrollActionReason::kByMouseWheel);
-    stats_recorded_ = true;
-  }
-
-  bool result = views::OverlayScrollBar::OnMouseWheel(event);
-
-  if (observer_)
-    observer_->OnMessageCenterScrolled();
-
-  return result;
-}
-
-const char* MessageCenterScrollBar::GetClassName() const {
-  return "MessageCenterScrollBar";
-}
-
-void MessageCenterScrollBar::OnGestureEvent(ui::GestureEvent* event) {
-  if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN) {
-    if (!presentation_time_recorder_ && GetWidget()) {
-      presentation_time_recorder_ = CreatePresentationTimeHistogramRecorder(
-          GetWidget()->GetCompositor(), kMessageCenterScrollHistogram,
-          kMessageCenterScrollMaxLatencyHistogram);
-    }
-    if (!stats_recorded_) {
-      CollectScrollActionReason(ScrollActionReason::kByTouch);
-      stats_recorded_ = true;
-    }
-  }
-
-  if (event->type() == ui::ET_GESTURE_SCROLL_UPDATE) {
-    if (presentation_time_recorder_)
-      presentation_time_recorder_->RequestNext();
-  }
-
-  if (event->type() == ui::ET_GESTURE_END)
-    presentation_time_recorder_.reset();
-
-  views::OverlayScrollBar::OnGestureEvent(event);
-
-  if (observer_)
-    observer_->OnMessageCenterScrolled();
-}
-
-bool MessageCenterScrollBar::OnScroll(float dx, float dy) {
-  bool result = views::OverlayScrollBar::OnScroll(dx, dy);
-  if (observer_)
-    observer_->OnMessageCenterScrolled();
-
-  // Widget might be null in tests.
-  if (GetWidget() && !presentation_time_recorder_) {
-    // Create a recorder if needed. We stop and record metrics when the
-    // object goes out of scope (when message center is closed).
-    presentation_time_recorder_ = CreatePresentationTimeHistogramRecorder(
-        GetWidget()->GetCompositor(), kMessageCenterScrollHistogram,
-        kMessageCenterScrollMaxLatencyHistogram);
-  }
-  if (presentation_time_recorder_)
-    presentation_time_recorder_->RequestNext();
-
-  return result;
-}
-
-RoundedMessageCenterScrollBar::RoundedMessageCenterScrollBar(
-    MessageCenterScrollBar::Observer* observer)
+RoundedMessageCenterScrollBar::RoundedMessageCenterScrollBar(Observer* observer)
     : RoundedScrollBar(false), observer_(observer) {
   GetThumb()->layer()->SetVisible(features::IsNotificationScrollBarEnabled());
   GetThumb()->layer()->CompleteAllAnimations();
diff --git a/ash/system/message_center/message_center_scroll_bar.h b/ash/system/message_center/message_center_scroll_bar.h
index 9ae7432..920b08de 100644
--- a/ash/system/message_center/message_center_scroll_bar.h
+++ b/ash/system/message_center/message_center_scroll_bar.h
@@ -5,10 +5,10 @@
 #ifndef ASH_SYSTEM_MESSAGE_CENTER_MESSAGE_CENTER_SCROLL_BAR_H_
 #define ASH_SYSTEM_MESSAGE_CENTER_MESSAGE_CENTER_SCROLL_BAR_H_
 
+#include <memory>
+
 #include "ash/controls/rounded_scroll_bar.h"
-#include "ui/compositor/presentation_time_recorder.h"
 #include "ui/events/event.h"
-#include "ui/views/controls/scrollbar/overlay_scroll_bar.h"
 
 namespace ui {
 class PresentationTimeRecorder;
@@ -16,11 +16,14 @@
 
 namespace ash {
 
-// The scroll bar for message center. This is basically views::OverlayScrollBar
+// The scroll bar for message center. This is basically just a RoundedScrollBar
 // but also records the metrics for the type of scrolling (only the first event
 // after the message center opens is recorded) and scrolling performance.
-class MessageCenterScrollBar : public views::OverlayScrollBar {
+// TODO(b/257291597): Rename this file to match the class name.
+class RoundedMessageCenterScrollBar : public RoundedScrollBar {
  public:
+  METADATA_HEADER(RoundedMessageCenterScrollBar);
+
   class Observer {
    public:
     // Called when scroll event is triggered.
@@ -29,43 +32,7 @@
   };
 
   // |observer| can be null.
-  explicit MessageCenterScrollBar(Observer* observer);
-
-  MessageCenterScrollBar(const MessageCenterScrollBar&) = delete;
-  MessageCenterScrollBar& operator=(const MessageCenterScrollBar&) = delete;
-
-  ~MessageCenterScrollBar() override;
-
- private:
-  // View overrides:
-  bool OnKeyPressed(const ui::KeyEvent& event) override;
-  bool OnMouseWheel(const ui::MouseWheelEvent& event) override;
-  const char* GetClassName() const override;
-
-  // ui::EventHandler overrides:
-  void OnGestureEvent(ui::GestureEvent* event) override;
-
-  // views::ScrollDelegate overrides:
-  bool OnScroll(float dx, float dy) override;
-
-  // False if no event is recorded yet. True if the first event is recorded.
-  bool stats_recorded_ = false;
-
-  Observer* const observer_;
-
-  // Presentation time recorder for scrolling through notification list.
-  std::unique_ptr<ui::PresentationTimeRecorder> presentation_time_recorder_;
-};
-
-// The new scroll bar for message center. This class will replace
-// MessageCenterScrollBar in NotificationsRefresh feature.
-class RoundedMessageCenterScrollBar : public RoundedScrollBar {
- public:
-  METADATA_HEADER(RoundedMessageCenterScrollBar);
-
-  // |observer| can be null.
-  explicit RoundedMessageCenterScrollBar(
-      MessageCenterScrollBar::Observer* observer);
+  explicit RoundedMessageCenterScrollBar(Observer* observer);
 
   RoundedMessageCenterScrollBar(const RoundedMessageCenterScrollBar&) = delete;
   RoundedMessageCenterScrollBar& operator=(
@@ -88,7 +55,7 @@
   bool stats_recorded_ = false;
 
   // Unowned.
-  MessageCenterScrollBar::Observer* const observer_;
+  Observer* const observer_;
 
   // Presentation time recorder for scrolling through notification list.
   std::unique_ptr<ui::PresentationTimeRecorder> presentation_time_recorder_;
diff --git a/ash/system/network/network_icon.cc b/ash/system/network/network_icon.cc
index 742bcc4..f0d3a821 100644
--- a/ash/system/network/network_icon.cc
+++ b/ash/system/network/network_icon.cc
@@ -4,6 +4,7 @@
 
 #include "ash/system/network/network_icon.h"
 
+#include <algorithm>
 #include <tuple>
 #include <utility>
 
@@ -18,7 +19,6 @@
 #include "ash/system/network/network_icon_animation_observer.h"
 #include "ash/system/tray/tray_constants.h"
 #include "base/containers/flat_map.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chromeos/services/network_config/public/cpp/cros_network_config_util.h"
@@ -200,7 +200,7 @@
 
   int index =
       animation * nextafter(static_cast<float>(kNumConnectingImages), 0);
-  index = base::clamp(index, 0, kNumConnectingImages - 1);
+  index = std::clamp(index, 0, kNumConnectingImages - 1);
 
   auto map_key = std::make_tuple(
       is_bars_image, DarkLightModeControllerImpl::Get()->IsDarkModeEnabled(),
diff --git a/ash/system/night_light/night_light_controller_impl.cc b/ash/system/night_light/night_light_controller_impl.cc
index 8f4b9a6..c6960943 100644
--- a/ash/system/night_light/night_light_controller_impl.cc
+++ b/ash/system/night_light/night_light_controller_impl.cc
@@ -4,6 +4,7 @@
 
 #include "ash/system/night_light/night_light_controller_impl.h"
 
+#include <algorithm>
 #include <cmath>
 #include <memory>
 
@@ -19,7 +20,6 @@
 #include "ash/shell.h"
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/system/model/system_tray_model.h"
-#include "base/cxx17_backports.h"
 #include "base/functional/bind.h"
 #include "base/i18n/time_formatting.h"
 #include "base/logging.h"
@@ -168,7 +168,7 @@
 // 3 => Range [60 : 80).
 // 4 => Range [80 : 100] (most warm).
 int GetTemperatureRange(float temperature) {
-  return base::clamp(std::floor(5 * temperature), 0.0f, 4.0f);
+  return std::clamp(std::floor(5 * temperature), 0.0f, 4.0f);
 }
 
 // Returns the color matrix that corresponds to the given |temperature|.
@@ -356,7 +356,7 @@
     }
 
     start_temperature_ = current_temperature_;
-    target_temperature_ = base::clamp(new_target_temperature, 0.0f, 1.0f);
+    target_temperature_ = std::clamp(new_target_temperature, 0.0f, 1.0f);
 
     if (ui::ScopedAnimationDurationScaleMode::duration_multiplier() ==
         ui::ScopedAnimationDurationScaleMode::ZERO_DURATION) {
@@ -375,7 +375,7 @@
  private:
   // gfx::Animation:
   void AnimateToState(double state) override {
-    state = base::clamp(state, 0.0, 1.0);
+    state = std::clamp(state, 0.0, 1.0);
     current_temperature_ =
         start_temperature_ + (target_temperature_ - start_temperature_) * state;
   }
@@ -483,8 +483,8 @@
   // kTable[i+1].input_temperature exclude the upper bound, we clamp it to the
   // last input_temperature element of the table minus 1.
   const float temperature =
-      base::clamp<float>(temperature_in_kelvin, kTable[0].input_temperature,
-                         kTable[kTableSize - 1].input_temperature - 1);
+      std::clamp<float>(temperature_in_kelvin, kTable[0].input_temperature,
+                        kTable[kTableSize - 1].input_temperature - 1);
   for (size_t i = 0; i < kTableSize - 1; i++) {
     if (temperature >= kTable[i].input_temperature &&
         temperature < kTable[i + 1].input_temperature) {
diff --git a/ash/system/notification_center/notification_center_view.cc b/ash/system/notification_center/notification_center_view.cc
index 10a7a73..363dec6 100644
--- a/ash/system/notification_center/notification_center_view.cc
+++ b/ash/system/notification_center/notification_center_view.cc
@@ -89,23 +89,15 @@
       scroller_(new views::ScrollView()),
       notification_list_view_(new NotificationListView(this, model)),
       last_scroll_position_from_bottom_(0),
-      is_notifications_refresh_enabled_(
-          features::IsNotificationsRefreshEnabled()),
       animation_(std::make_unique<gfx::LinearAnimation>(this)),
       focus_search_(std::make_unique<views::FocusSearch>(this, false, false)) {
-  if (is_notifications_refresh_enabled_) {
-    auto* scroll_bar = new RoundedMessageCenterScrollBar(this);
-    scroll_bar->SetInsets(kScrollBarInsets);
-    scroll_bar_ = scroll_bar;
-  } else {
-    scroll_bar_ = new MessageCenterScrollBar(this);
-  }
+  auto* scroll_bar = new RoundedMessageCenterScrollBar(this);
+  scroll_bar->SetInsets(kScrollBarInsets);
+  scroll_bar_ = scroll_bar;
 
-  if (is_notifications_refresh_enabled_) {
-    layout_manager_ = SetLayoutManager(std::make_unique<views::BoxLayout>(
-        views::BoxLayout::Orientation::kVertical,
-        gfx::Insets(kMessageCenterPadding)));
-  }
+  layout_manager_ = SetLayoutManager(std::make_unique<views::BoxLayout>(
+      views::BoxLayout::Orientation::kVertical,
+      gfx::Insets(kMessageCenterPadding)));
 }
 
 NotificationCenterView::~NotificationCenterView() {
@@ -124,10 +116,6 @@
 void NotificationCenterView::Init() {
   notification_list_view_->Init();
 
-  if (!is_notifications_refresh_enabled_) {
-    AddChildView(notification_bar_);
-  }
-
   // Need to set the transparent background explicitly, since ScrollView has
   // set the default opaque background color.
   // TODO(crbug.com/1247455): Be able to do
@@ -137,11 +125,9 @@
   scroller_->SetBackgroundColor(absl::nullopt);
   scroller_->SetVerticalScrollBar(base::WrapUnique(scroll_bar_));
   scroller_->SetDrawOverflowIndicator(false);
-  if (is_notifications_refresh_enabled_) {
-    scroller_->SetPaintToLayer();
-    scroller_->layer()->SetRoundedCornerRadius(
-        gfx::RoundedCornersF{kMessageCenterScrollViewCornerRadius});
-  }
+  scroller_->SetPaintToLayer();
+  scroller_->layer()->SetRoundedCornerRadius(
+      gfx::RoundedCornersF{kMessageCenterScrollViewCornerRadius});
 
   AddChildView(scroller_);
 
@@ -160,9 +146,7 @@
                             base::Unretained(this)));
   }
 
-  if (is_notifications_refresh_enabled_) {
-    AddChildView(notification_bar_);
-  }
+  AddChildView(notification_bar_);
 }
 
 bool NotificationCenterView::UpdateNotificationBar() {
@@ -181,11 +165,8 @@
 
   int max_scroller_height = max_height;
   if (notification_bar_->GetVisible()) {
-    max_scroller_height -=
-        is_notifications_refresh_enabled_
-            ? notification_bar_->GetPreferredSize().height() +
-                  2 * kMessageCenterPadding
-            : kStackedNotificationBarHeight;
+    max_scroller_height -= notification_bar_->GetPreferredSize().height() +
+                           2 * kMessageCenterPadding;
   }
   scroller_->ClipHeightTo(0, max_scroller_height);
 }
@@ -303,73 +284,6 @@
   focus_manager_ = nullptr;
 }
 
-void NotificationCenterView::Layout() {
-  if (is_notifications_refresh_enabled_) {
-    return views::View::Layout();
-  }
-
-  if (notification_bar_->GetVisible()) {
-    gfx::Rect counter_bounds(GetContentsBounds());
-
-    int notification_bar_expanded_height = kStackedNotificationBarHeight;
-
-    int notification_bar_height = collapsed_
-                                      ? kStackedNotificationBarCollapsedHeight
-                                      : notification_bar_expanded_height;
-    int notification_bar_offset = 0;
-    if (animation_state_ ==
-        NotificationCenterAnimationState::HIDE_STACKING_BAR) {
-      notification_bar_offset = GetAnimationValue() * notification_bar_height;
-    }
-
-    counter_bounds.set_height(notification_bar_height);
-    counter_bounds.set_y(counter_bounds.y() - notification_bar_offset);
-    notification_bar_->SetBoundsRect(counter_bounds);
-
-    gfx::Rect scroller_bounds(GetContentsBounds());
-
-    scroller_bounds.Inset(gfx::Insets::TLBR(
-        notification_bar_height - notification_bar_offset, 0, 0, 0));
-    scroller_->SetBoundsRect(scroller_bounds);
-  } else {
-    scroller_->SetBoundsRect(GetContentsBounds());
-  }
-
-  ScrollToTarget();
-}
-
-gfx::Size NotificationCenterView::CalculatePreferredSize() const {
-  if (is_notifications_refresh_enabled_) {
-    return views::View::CalculatePreferredSize();
-  }
-
-  gfx::Size preferred_size = scroller_->GetPreferredSize();
-
-  if (notification_bar_->GetVisible()) {
-    int bar_height = kStackedNotificationBarHeight;
-
-    if (animation_state_ ==
-        NotificationCenterAnimationState::HIDE_STACKING_BAR) {
-      bar_height -= GetAnimationValue() * bar_height;
-    }
-    preferred_size.set_height(preferred_size.height() + bar_height);
-  }
-
-  if (animation_state_ == NotificationCenterAnimationState::COLLAPSE) {
-    int height = preferred_size.height() * (1.0 - GetAnimationValue());
-
-    if (collapsed_) {
-      height = std::max(kStackedNotificationBarCollapsedHeight, height);
-    }
-
-    preferred_size.set_height(height);
-  } else if (collapsed_) {
-    preferred_size.set_height(kStackedNotificationBarCollapsedHeight);
-  }
-
-  return preferred_size;
-}
-
 void NotificationCenterView::OnViewBoundsChanged(views::View* observed_view) {
   UpdateNotificationBar();
 }
@@ -599,16 +513,8 @@
     return notification_list_view_->GetAllNotifications();
   }
 
-  if (is_notifications_refresh_enabled_) {
-    const int y_offset = scroller_->GetVisibleRect().bottom() - scroller_->y();
-    return notification_list_view_->GetNotificationsBelowY(y_offset);
-  }
-
-  const int notification_bar_height =
-      IsNotificationBarVisible() ? kStackedNotificationBarHeight : 0;
-  const int y_offset = scroller_->GetVisibleRect().y() - scroller_->y() +
-                       notification_bar_height;
-  return notification_list_view_->GetNotificationsAboveY(y_offset);
+  const int y_offset = scroller_->GetVisibleRect().bottom() - scroller_->y();
+  return notification_list_view_->GetNotificationsBelowY(y_offset);
 }
 
 std::vector<std::string>
diff --git a/ash/system/notification_center/notification_center_view.h b/ash/system/notification_center/notification_center_view.h
index efb5116..c9a0235 100644
--- a/ash/system/notification_center/notification_center_view.h
+++ b/ash/system/notification_center/notification_center_view.h
@@ -61,7 +61,7 @@
 // Manages scrolling of notification list.
 class ASH_EXPORT NotificationCenterView
     : public views::View,
-      public MessageCenterScrollBar::Observer,
+      public RoundedMessageCenterScrollBar::Observer,
       public views::FocusChangeListener,
       public gfx::AnimationDelegate,
       public views::ViewObserver {
@@ -148,8 +148,6 @@
   // views::View:
   void AddedToWidget() override;
   void RemovedFromWidget() override;
-  void Layout() override;
-  gfx::Size CalculatePreferredSize() const override;
 
   // views::ViewObserver:
   void OnViewBoundsChanged(views::View* observed_view) override;
@@ -215,8 +213,6 @@
   // Position from the bottom of scroll contents in dip.
   int last_scroll_position_from_bottom_;
 
-  const bool is_notifications_refresh_enabled_;
-
   // The height available to the message center view. This is the remaining
   // height of the system tray excluding the system menu (which can be expanded
   // or collapsed).
diff --git a/ash/system/phonehub/app_stream_launcher_view_unittest.cc b/ash/system/phonehub/app_stream_launcher_view_unittest.cc
index 238b3a6a..2d1eb296 100644
--- a/ash/system/phonehub/app_stream_launcher_view_unittest.cc
+++ b/ash/system/phonehub/app_stream_launcher_view_unittest.cc
@@ -81,7 +81,7 @@
             index));
   }
 
-  const gfx::Image /*cololr_icon=*/CreateTestImage() {
+  const gfx::Image CreateTestImage() {
     SkBitmap bitmap;
     bitmap.allocN32Pixels(60, 60);
     gfx::ImageSkia image_skia = gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
@@ -133,7 +133,8 @@
                     .size());
 
   auto app1 = phonehub::Notification::AppMetadata(
-      app_visible_name, package_name, /*cololr_icon=*/CreateTestImage(),
+      app_visible_name, package_name, /*color_icon=*/CreateTestImage(),
+      /*monochrome_icon_mask=*/absl::nullopt,
       /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id,
       phonehub::proto::AppStreamabilityStatus::STREAMABLE);
   std::vector<phonehub::Notification::AppMetadata> apps;
@@ -163,7 +164,8 @@
   const char16_t app_visible_name[] = u"Fake App";
   const char package_name[] = "com.fakeapp";
   auto app1 = phonehub::Notification::AppMetadata(
-      app_visible_name, package_name, /*cololr_icon=*/CreateTestImage(),
+      app_visible_name, package_name, /*color_icon=*/CreateTestImage(),
+      /*monochrome_icon_mask=*/absl::nullopt,
       /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id,
       phonehub::proto::AppStreamabilityStatus::STREAMABLE);
   std::vector<phonehub::Notification::AppMetadata> apps;
@@ -188,7 +190,8 @@
   const char package_name[] = "com.fakeapp";
 
   auto app1 = phonehub::Notification::AppMetadata(
-      app_visible_name, package_name, /*cololr_icon=*/CreateTestImage(),
+      app_visible_name, package_name, /*color_icon=*/CreateTestImage(),
+      /*monochrome_icon_mask=*/absl::nullopt,
       /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id,
       phonehub::proto::AppStreamabilityStatus::STREAMABLE);
   std::vector<phonehub::Notification::AppMetadata> apps;
@@ -227,7 +230,7 @@
   const char package_name[] = "com.fakeapp";
 
   auto app1 = phonehub::Notification::AppMetadata(
-      app_visible_name, package_name, /*cololr_icon=*/CreateTestImage(),
+      app_visible_name, package_name, /*color_icon=*/CreateTestImage(),
       /*monochrome_icon_mask=*/absl::nullopt,
       /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id,
       phonehub::proto::AppStreamabilityStatus::STREAMABLE);
@@ -261,7 +264,7 @@
   const char package_name[] = "com.fakeapp";
 
   auto app1 = phonehub::Notification::AppMetadata(
-      app_visible_name, package_name, /*cololr_icon=*/CreateTestImage(),
+      app_visible_name, package_name, /*color_icon=*/CreateTestImage(),
       /*monochrome_icon_mask=*/absl::nullopt,
       /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id,
       phonehub::proto::AppStreamabilityStatus::STREAMABLE);
@@ -308,7 +311,7 @@
   const char package_name[] = "com.fakeapp";
 
   auto app1 = phonehub::Notification::AppMetadata(
-      app_visible_name, package_name, /*cololr_icon=*/CreateTestImage(),
+      app_visible_name, package_name, /*color_icon=*/CreateTestImage(),
       /*monochrome_icon_mask=*/absl::nullopt,
       /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id,
       phonehub::proto::AppStreamabilityStatus::STREAMABLE);
@@ -348,7 +351,7 @@
   const char package_name[] = "com.fakeapp";
 
   auto app1 = phonehub::Notification::AppMetadata(
-      app_visible_name, package_name, /*cololr_icon=*/CreateTestImage(),
+      app_visible_name, package_name, /*color_icon=*/CreateTestImage(),
       /*monochrome_icon_mask=*/absl::nullopt,
       /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id,
       phonehub::proto::AppStreamabilityStatus::BLOCK_LISTED);
@@ -388,7 +391,7 @@
   const char package_name[] = "com.fakeapp";
 
   auto app1 = phonehub::Notification::AppMetadata(
-      app_visible_name, package_name, /*cololr_icon=*/CreateTestImage(),
+      app_visible_name, package_name, /*color_icon=*/CreateTestImage(),
       /*monochrome_icon_mask=*/absl::nullopt,
       /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id,
       phonehub::proto::AppStreamabilityStatus::BLOCK_LISTED);
diff --git a/ash/system/phonehub/phone_hub_recent_apps_view.cc b/ash/system/phonehub/phone_hub_recent_apps_view.cc
index 5f319dbc..c0bd89b 100644
--- a/ash/system/phonehub/phone_hub_recent_apps_view.cc
+++ b/ash/system/phonehub/phone_hub_recent_apps_view.cc
@@ -4,6 +4,7 @@
 
 #include "ash/system/phonehub/phone_hub_recent_apps_view.h"
 
+#include <algorithm>
 #include <memory>
 #include <numeric>
 #include <vector>
@@ -23,7 +24,6 @@
 #include "ash/system/tray/tray_constants.h"
 #include "ash/webui/eche_app_ui/mojom/eche_app.mojom.h"
 #include "ash/webui/eche_app_ui/system_info_provider.h"
-#include "base/cxx17_backports.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/ranges/algorithm.h"
 #include "chromeos/ash/components/phonehub/notification.h"
@@ -105,8 +105,8 @@
     spacing = (child_area.width() - visible_child_width -
                kRecentAppButtonsViewHorizontalPadding * 2) /
               (static_cast<int>(visible_children.size()) - 1);
-    spacing = base::clamp(spacing, kRecentAppButtonMinSpacing,
-                          kRecentAppButtonDefaultSpacing);
+    spacing = std::clamp(spacing, kRecentAppButtonMinSpacing,
+                         kRecentAppButtonDefaultSpacing);
   }
 
   int child_x = child_area.x() + kRecentAppButtonsViewHorizontalPadding;
diff --git a/ash/system/power/battery_image_source.cc b/ash/system/power/battery_image_source.cc
index 29ce06e2..d2377ca 100644
--- a/ash/system/power/battery_image_source.cc
+++ b/ash/system/power/battery_image_source.cc
@@ -4,10 +4,11 @@
 
 #include "ash/system/power/battery_image_source.h"
 
+#include <algorithm>
+
 #include "ash/constants/ash_features.h"
 #include "ash/resources/vector_icons/vector_icons.h"
 #include "ash/style/ash_color_provider.h"
-#include "base/cxx17_backports.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/gfx/geometry/rect_f.h"
@@ -84,7 +85,7 @@
       std::floor(info_.charge_percent / 100.0 * icon_bounds.height());
   const float min_charge_level = dsf * kMinVisualChargeLevel;
   charge_level =
-      base::clamp(charge_level, min_charge_level, icon_bounds.height());
+      std::clamp(charge_level, min_charge_level, icon_bounds.height());
 
   const float charge_y = icon_bounds.bottom() - charge_level;
   gfx::RectF clip_rect(0, charge_y, size().width() * dsf,
diff --git a/ash/system/privacy_screen/privacy_screen_toast_controller.cc b/ash/system/privacy_screen/privacy_screen_toast_controller.cc
index 0146eb5..def5919 100644
--- a/ash/system/privacy_screen/privacy_screen_toast_controller.cc
+++ b/ash/system/privacy_screen/privacy_screen_toast_controller.cc
@@ -4,6 +4,8 @@
 
 #include "ash/system/privacy_screen/privacy_screen_toast_controller.h"
 
+#include <algorithm>
+
 #include "ash/accessibility/accessibility_controller_impl.h"
 #include "ash/bubble/bubble_constants.h"
 #include "ash/shelf/shelf.h"
@@ -14,7 +16,6 @@
 #include "ash/system/unified/unified_system_tray.h"
 #include "ash/system/unified/unified_system_tray_bubble.h"
 #include "ash/system/unified/unified_system_tray_view.h"
-#include "base/cxx17_backports.h"
 #include "base/functional/bind.h"
 
 namespace ash {
@@ -143,8 +144,8 @@
         /*enabled=*/privacy_screen_controller->GetEnabled(),
         /*managed=*/privacy_screen_controller->IsManaged());
     int width =
-        base::clamp(toast_view_->GetPreferredSize().width(),
-                    kPrivacyScreenToastMinWidth, kPrivacyScreenToastMaxWidth);
+        std::clamp(toast_view_->GetPreferredSize().width(),
+                   kPrivacyScreenToastMinWidth, kPrivacyScreenToastMaxWidth);
     bubble_view_->SetPreferredWidth(width);
   }
 }
diff --git a/ash/system/tray/tray_constants.h b/ash/system/tray/tray_constants.h
index d83e0ec..a50711c3 100644
--- a/ash/system/tray/tray_constants.h
+++ b/ash/system/tray/tray_constants.h
@@ -136,7 +136,6 @@
 
 constexpr int kMessageCenterCollapseThreshold = 175;
 constexpr int kStackedNotificationBarHeight = 32;
-constexpr int kStackedNotificationBarCollapsedHeight = 40;
 constexpr int kNotificationIconStackThreshold = 28;
 constexpr int kUnifiedSliderViewSpacing = 12;
 constexpr int kUnifiedMessageCenterBubbleSpacing = 8;
diff --git a/ash/system/unified/top_shortcuts_view.cc b/ash/system/unified/top_shortcuts_view.cc
index 3087a669..a3e560ea 100644
--- a/ash/system/unified/top_shortcuts_view.cc
+++ b/ash/system/unified/top_shortcuts_view.cc
@@ -4,6 +4,7 @@
 
 #include "ash/system/unified/top_shortcuts_view.h"
 
+#include <algorithm>
 #include <cstddef>
 #include <memory>
 #include <numeric>
@@ -28,7 +29,6 @@
 #include "ash/system/unified/user_chooser_detailed_view_controller.h"
 #include "ash/system/unified/user_chooser_view.h"
 #include "ash/system/user/login_status.h"
-#include "base/cxx17_backports.h"
 #include "base/functional/bind.h"
 #include "base/ranges/algorithm.h"
 #include "components/prefs/pref_registry_simple.h"
@@ -71,8 +71,8 @@
   if (visible_children.size() > 1) {
     spacing = (child_area.width() - visible_child_width) /
               (static_cast<int>(visible_children.size()) - 1);
-    spacing = base::clamp(spacing, kUnifiedTopShortcutButtonMinSpacing,
-                          kUnifiedTopShortcutButtonDefaultSpacing);
+    spacing = std::clamp(spacing, kUnifiedTopShortcutButtonMinSpacing,
+                         kUnifiedTopShortcutButtonDefaultSpacing);
   }
 
   int x = child_area.x();
@@ -90,7 +90,7 @@
           child_area.width() -
           (static_cast<int>(visible_children.size()) - 1) * spacing -
           (visible_child_width - width);
-      width = base::clamp(width, 0, std::max(0, remainder));
+      width = std::clamp(width, 0, std::max(0, remainder));
     }
 
     child->SetBounds(x, child_y, width, child->GetHeightForWidth(width));
diff --git a/ash/system/unified/unified_system_tray_controller.cc b/ash/system/unified/unified_system_tray_controller.cc
index b6ed33c..3d095d46 100644
--- a/ash/system/unified/unified_system_tray_controller.cc
+++ b/ash/system/unified/unified_system_tray_controller.cc
@@ -3,6 +3,8 @@
 // found in the LICENSE file.
 
 #include "ash/system/unified/unified_system_tray_controller.h"
+
+#include <algorithm>
 #include <memory>
 
 #include "ash/capture_mode/capture_mode_feature_pod_controller.h"
@@ -67,7 +69,6 @@
 #include "ash/system/unified/user_chooser_detailed_view_controller.h"
 #include "ash/wm/lock_state_controller.h"
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
-#include "base/cxx17_backports.h"
 #include "base/functional/bind.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/metrics/histogram_macros.h"
@@ -896,9 +897,9 @@
   // If already expanded, only consider swiping down. Otherwise, only consider
   // swiping up.
   if (was_expanded_) {
-    return base::clamp(1.0 - std::max(0.0, y_diff) / drag_threshold_, 0.0, 1.0);
+    return std::clamp(1.0 - std::max(0.0, y_diff) / drag_threshold_, 0.0, 1.0);
   } else {
-    return base::clamp(std::max(0.0, -y_diff) / drag_threshold_, 0.0, 1.0);
+    return std::clamp(std::max(0.0, -y_diff) / drag_threshold_, 0.0, 1.0);
   }
 }
 
diff --git a/ash/webui/personalization_app/resources/js/ambient/ambient_preview_large_element.html b/ash/webui/personalization_app/resources/js/ambient/ambient_preview_large_element.html
index 0d026f3..dba3811 100644
--- a/ash/webui/personalization_app/resources/js/ambient/ambient_preview_large_element.html
+++ b/ash/webui/personalization_app/resources/js/ambient/ambient_preview_large_element.html
@@ -10,7 +10,7 @@
       '. mainpage-desc  .       thumbnail .'
       '. .              .       .         .';
     grid-template-columns: 20px auto 192px auto 20px;
-    grid-template-rows: auto auto 20px 192px auto 20px;
+    grid-template-rows: auto auto 20px 192px 1fr 20px;
     height: 100%;
   }
 
@@ -23,7 +23,7 @@
       '. mainpage-desc .'
       '. .             .';
     grid-template-columns: 20px minmax(0,1fr) 20px;
-    grid-template-rows: auto auto 20px 130px auto 18px;
+    grid-template-rows: auto auto 20px 130px 1fr 18px;
   }
 
   #container.jelly-disabled {
@@ -59,7 +59,7 @@
   }
 
   #ambientSubpageLink {
-    --cr-icon-button-size: 48px;
+    --cr-icon-button-size: 44px;
     /* Make the arrow align with the thumbnail image */
     margin-inline-end: -18px;
   }
@@ -67,7 +67,7 @@
   #ambientLabel>h2 {
     color: var(--cros-text-color-primary);
     font: var(--personalization-app-label-font);
-    margin: 14px 0;
+    margin: 12px 0;
   }
 
   #ambientLabel.enterprise {
@@ -126,7 +126,7 @@
 
   :host-context(body.jelly-enabled) #imageContainer,
   :host-context(body.jelly-enabled) #imagePlaceholder {
-    aspect-ratio: 460/274;
+    aspect-ratio: 340/220;
     max-width: 460px;
     min-width: 278px;
   }
@@ -172,7 +172,7 @@
   #albumTitle {
     color: var(--cros-text-color-primary);
     font: var(--cros-display-7-font);
-    margin-top: 16px;
+    margin-top: 10px;
   }
 
   #albumTitle.jelly-disabled {
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 0f2ff380..7090445 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
@@ -39,10 +39,10 @@
     display: grid;
     gap: 12px;
     grid-template-columns: repeat(4, minmax(0,1fr));
-    margin: 16px 0;
+    margin: 16px 0 12px;
   }
 
-  cr-button {
+  #container cr-button {
     background-color: var(--cros-sys-app_base_shaded);
     border: none;
     border-radius: 16px;
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_preview_element.html b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_preview_element.html
index 1442c925d..8082f82 100644
--- a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_preview_element.html
+++ b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_preview_element.html
@@ -27,7 +27,7 @@
     color: var(--cros-text-color-primary);
     display: inline-block;
     font: var(--personalization-app-label-font);
-    margin: 14px 0;
+    margin: 12px 0;
   }
 
   iron-icon[icon='personalization:managed'] {
@@ -35,7 +35,7 @@
   }
 
   #wallpaperButton {
-    --cr-icon-button-size: 48px;
+    --cr-icon-button-size: 44px;
     /* Make the arrow align with the thumbnail image */
     margin-inline-end: -18px;
   }
@@ -75,12 +75,12 @@
   }
 
   :host-context(body.jelly-enabled) #container {
-      grid-template-rows: auto auto 20px 1fr 24px;
+      grid-template-rows: auto auto 16px auto 20px;
   }
 
   :host-context(body.jelly-enabled) #imageContainer,
   :host-context(body.jelly-enabled) #imagePlaceholder {
-    aspect-ratio: 460/274;
+    aspect-ratio: 340/220;
     max-width: 460px;
     min-width: 278px;
   }
diff --git a/ash/wm/desks/cros_next_default_desk_button.cc b/ash/wm/desks/cros_next_default_desk_button.cc
index 7e73f46..a04686d 100644
--- a/ash/wm/desks/cros_next_default_desk_button.cc
+++ b/ash/wm/desks/cros_next_default_desk_button.cc
@@ -4,6 +4,8 @@
 
 #include "ash/wm/desks/cros_next_default_desk_button.h"
 
+#include <algorithm>
+
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/wm/desks/desk.h"
 #include "ash/wm/desks/desk_mini_view.h"
@@ -67,7 +69,7 @@
   // tests with extreme abnormal size of display.
   const int min_width = std::min(preview_width, kDefaultDeskButtonMinWidth);
   const int max_width = std::max(preview_width, kDefaultDeskButtonMinWidth);
-  const int width = base::clamp(
+  const int width = std::clamp(
       label_width + 2 * kDefaultButtonHorizontalPadding, min_width, max_width);
   return gfx::Size(width, kDefaultDeskButtonHeight);
 }
diff --git a/ash/wm/desks/desk_mini_view.cc b/ash/wm/desks/desk_mini_view.cc
index 81da3a67..20fb5f0 100644
--- a/ash/wm/desks/desk_mini_view.cc
+++ b/ash/wm/desks/desk_mini_view.cc
@@ -25,7 +25,6 @@
 #include "ash/wm/overview/overview_constants.h"
 #include "ash/wm/overview/overview_grid.h"
 #include "ash/wm/overview/overview_utils.h"
-#include "base/cxx17_backports.h"
 #include "base/functional/bind.h"
 #include "base/i18n/rtl.h"
 #include "base/strings/string_util.h"
@@ -583,7 +582,7 @@
   const int max_width = std::max(preview_bounds.width() - focus_ring_length,
                                  kMinDeskNameViewWidth);
   const int text_width =
-      base::clamp(desk_name_view_size.width(), min_width, max_width);
+      std::clamp(desk_name_view_size.width(), min_width, max_width);
   const int desk_name_view_x =
       preview_bounds.x() + (preview_bounds.width() - text_width) / 2;
   gfx::Rect desk_name_view_bounds{desk_name_view_x,
diff --git a/ash/wm/desks/desk_preview_view.cc b/ash/wm/desks/desk_preview_view.cc
index 39aa819..6346890 100644
--- a/ash/wm/desks/desk_preview_view.cc
+++ b/ash/wm/desks/desk_preview_view.cc
@@ -4,6 +4,7 @@
 
 #include "ash/wm/desks/desk_preview_view.h"
 
+#include <algorithm>
 #include <functional>
 #include <memory>
 #include <utility>
@@ -31,7 +32,6 @@
 #include "base/containers/contains.h"
 #include "base/containers/flat_map.h"
 #include "base/containers/flat_set.h"
-#include "base/cxx17_backports.h"
 #include "base/ranges/algorithm.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "chromeos/ui/wm/features.h"
@@ -395,8 +395,8 @@
       root->bounds().width() <= kUseSmallerHeightDividerWidthThreshold
           ? kRootHeightDividerForSmallScreen
           : kRootHeightDivider;
-  return base::clamp(root->bounds().height() / height_divider,
-                     kDeskPreviewMinHeight, kDeskPreviewMaxHeight);
+  return std::clamp(root->bounds().height() / height_divider,
+                    kDeskPreviewMinHeight, kDeskPreviewMaxHeight);
 }
 
 void DeskPreviewView::SetHighlightOverlayVisibility(bool visible) {
diff --git a/ash/wm/desks/desks_controller.cc b/ash/wm/desks/desks_controller.cc
index 016a097..077047f7 100644
--- a/ash/wm/desks/desks_controller.cc
+++ b/ash/wm/desks/desks_controller.cc
@@ -4,6 +4,7 @@
 
 #include "ash/wm/desks/desks_controller.h"
 
+#include <algorithm>
 #include <memory>
 #include <utility>
 
@@ -54,7 +55,6 @@
 #include "base/check_op.h"
 #include "base/containers/contains.h"
 #include "base/containers/unique_ptr_adapters.h"
-#include "base/cxx17_backports.h"
 #include "base/debug/crash_logging.h"
 #include "base/debug/dump_without_crashing.h"
 #include "base/functional/bind.h"
@@ -1542,8 +1542,8 @@
   int new_user_active_desk_index =
       /* This is a default initialized index to 0 if the id doesn't exist. */
       user_to_active_desk_index_[current_account_id_];
-  new_user_active_desk_index = base::clamp(new_user_active_desk_index, 0,
-                                           static_cast<int>(desks_.size()) - 1);
+  new_user_active_desk_index = std::clamp(new_user_active_desk_index, 0,
+                                          static_cast<int>(desks_.size()) - 1);
 
   ActivateDesk(desks_[new_user_active_desk_index].get(),
                DesksSwitchSource::kUserSwitch);
diff --git a/ash/wm/desks/root_window_desk_switch_animator.cc b/ash/wm/desks/root_window_desk_switch_animator.cc
index 9b486870..14479843 100644
--- a/ash/wm/desks/root_window_desk_switch_animator.cc
+++ b/ash/wm/desks/root_window_desk_switch_animator.cc
@@ -4,6 +4,8 @@
 
 #include "ash/wm/desks/root_window_desk_switch_animator.h"
 
+#include <algorithm>
+
 #include "ash/constants/ash_features.h"
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/screen_util.h"
@@ -13,7 +15,6 @@
 #include "ash/wm/desks/desks_controller.h"
 #include "ash/wm/desks/desks_util.h"
 #include "base/auto_reset.h"
-#include "base/cxx17_backports.h"
 #include "base/functional/bind.h"
 #include "base/logging.h"
 #include "base/strings/string_number_conversions.h"
@@ -246,10 +247,10 @@
   float translation_x =
       animation_layer->transform().To2dTranslation().x() + translation_delta_x;
   translation_x =
-      base::clamp(translation_x,
-                  static_cast<float>(-animation_layer->bounds().width() +
-                                     visible_bounds_width),
-                  0.f);
+      std::clamp(translation_x,
+                 static_cast<float>(-animation_layer->bounds().width() +
+                                    visible_bounds_width),
+                 0.f);
   gfx::Transform transform;
   transform.Translate(translation_x, 0.f);
   base::AutoReset<bool> auto_reset(&setting_new_transform_, true);
diff --git a/ash/wm/desks/zero_state_button.cc b/ash/wm/desks/zero_state_button.cc
index 0be7eda4..e42f806a 100644
--- a/ash/wm/desks/zero_state_button.cc
+++ b/ash/wm/desks/zero_state_button.cc
@@ -4,6 +4,8 @@
 
 #include "ash/wm/desks/zero_state_button.h"
 
+#include <algorithm>
+
 #include "ash/accessibility/accessibility_controller_impl.h"
 #include "ash/shell.h"
 #include "ash/strings/grit/ash_strings.h"
@@ -13,7 +15,6 @@
 #include "ash/wm/desks/desk_preview_view.h"
 #include "ash/wm/desks/desks_bar_view.h"
 #include "ash/wm/desks/desks_controller.h"
-#include "base/cxx17_backports.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
 #include "ui/gfx/canvas.h"
@@ -82,8 +83,8 @@
   const int max_width =
       std::max(preview_width, kZeroStateDefaultDeskButtonMinWidth);
   const int width =
-      base::clamp(label_width + 2 * kZeroStateDefaultButtonHorizontalPadding,
-                  min_width, max_width);
+      std::clamp(label_width + 2 * kZeroStateDefaultButtonHorizontalPadding,
+                 min_width, max_width);
   return gfx::Size(width, kZeroStateButtonHeight);
 }
 
diff --git a/ash/wm/gestures/back_gesture/back_gesture_affordance.cc b/ash/wm/gestures/back_gesture/back_gesture_affordance.cc
index 9b91f780..71b9db9 100644
--- a/ash/wm/gestures/back_gesture/back_gesture_affordance.cc
+++ b/ash/wm/gestures/back_gesture/back_gesture_affordance.cc
@@ -4,6 +4,8 @@
 
 #include "ash/wm/gestures/back_gesture/back_gesture_affordance.h"
 
+#include <algorithm>
+
 #include "ash/display/screen_orientation_controller.h"
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/public/cpp/style/scoped_light_mode_as_default.h"
@@ -15,7 +17,6 @@
 #include "ash/wm/splitview/split_view_controller.h"
 #include "ash/wm/splitview/split_view_divider.h"
 #include "ash/wm/window_util.h"
-#include "base/cxx17_backports.h"
 #include "base/i18n/rtl.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "components/vector_icons/vector_icons.h"
@@ -323,7 +324,7 @@
                    kBackgroundRadius;
 
   float y_progress = y_drag_amount / kDistanceForFullYProgress;
-  y_drag_progress_ = base::clamp(y_progress, -1.0f, 1.0f);
+  y_drag_progress_ = std::clamp(y_progress, -1.0f, 1.0f);
 
   during_reverse_dragging_ = during_reverse_dragging;
 
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc
index c8826db..931d395e 100644
--- a/ash/wm/overview/overview_grid.cc
+++ b/ash/wm/overview/overview_grid.cc
@@ -4,6 +4,7 @@
 
 #include "ash/wm/overview/overview_grid.h"
 
+#include <algorithm>
 #include <functional>
 #include <memory>
 #include <utility>
@@ -60,7 +61,6 @@
 #include "ash/wm/workspace/workspace_layout_manager.h"
 #include "ash/wm/workspace_controller.h"
 #include "base/containers/adapters.h"
-#include "base/cxx17_backports.h"
 #include "base/functional/bind.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/ranges/algorithm.h"
@@ -1378,7 +1378,7 @@
 
     OverviewItem* nudged_item = window_list_[data.index].get();
     double nudge_param = value * value / 30.0;
-    nudge_param = base::clamp(nudge_param, 0.0, 1.0);
+    nudge_param = std::clamp(nudge_param, 0.0, 1.0);
     gfx::RectF bounds =
         gfx::Tween::RectFValueBetween(nudge_param, data.src, data.dst);
     nudged_item->SetBounds(bounds, OVERVIEW_ANIMATION_NONE);
@@ -1570,7 +1570,7 @@
 bool OverviewGrid::UpdateScrollOffset(float delta) {
   float new_scroll_offset = scroll_offset_;
   new_scroll_offset += delta;
-  new_scroll_offset = base::clamp(new_scroll_offset, scroll_offset_min_, 0.f);
+  new_scroll_offset = std::clamp(new_scroll_offset, scroll_offset_min_, 0.f);
 
   // For flings, we want to return false if we hit one of the edges, which is
   // when |new_scroll_offset| is exactly 0.f or |scroll_offset_min_|.
@@ -2328,13 +2328,13 @@
   // `rightmost_window_right` may have been modified by an earlier scroll.
   // `scroll_offset_` is added to adjust for that. If `rightmost_window_right`
   // is less than `total_bounds.right()`, the grid cannot be scrolled. Set
-  // `scroll_offset_min_` to 0 so that `base::clamp()` is happy.
+  // `scroll_offset_min_` to 0 so that `std::clamp()` is happy.
   rightmost_window_right -= scroll_offset_;
   scroll_offset_min_ = total_bounds.right() - rightmost_window_right;
   if (scroll_offset_min_ > 0.f)
     scroll_offset_min_ = 0.f;
 
-  scroll_offset_ = base::clamp(scroll_offset_, scroll_offset_min_, 0.f);
+  scroll_offset_ = std::clamp(scroll_offset_, scroll_offset_min_, 0.f);
 
   // Map which contains up to |kTabletLayoutRow| entries with information on the
   // last items right bound per row. Used so we can place the next item directly
diff --git a/ash/wm/overview/overview_window_drag_controller.cc b/ash/wm/overview/overview_window_drag_controller.cc
index 05bd97d..904844d 100644
--- a/ash/wm/overview/overview_window_drag_controller.cc
+++ b/ash/wm/overview/overview_window_drag_controller.cc
@@ -33,7 +33,6 @@
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
 #include "ash/wm/window_positioning_utils.h"
 #include "ash/wm/window_util.h"
-#include "base/cxx17_backports.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
 #include "base/metrics/histogram_functions.h"
@@ -535,7 +534,7 @@
               kDragToCloseDistanceThresholdDp;
   overview_session_->GetGridWithRootWindow(item_->root_window())
       ->UpdateNudge(item_, val);
-  val = base::clamp(val, 0.f, 1.f);
+  val = std::clamp(val, 0.f, 1.f);
   float opacity = original_opacity_;
   if (opacity > kItemMinOpacity)
     opacity = original_opacity_ - val * (original_opacity_ - kItemMinOpacity);
@@ -636,7 +635,7 @@
                                       desks_bar_data.desks_bar_bounds) /
                 desks_bar_data.shrink_region_distance.x();
       }
-      value = base::clamp(value, 0.f, 1.f);
+      value = std::clamp(value, 0.f, 1.f);
       const gfx::SizeF size_value =
           gfx::Tween::SizeFValueBetween(1.f - value, original_scaled_size_,
                                         desks_bar_data.on_desks_bar_item_size);
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc
index f6667929..d779739 100644
--- a/ash/wm/splitview/split_view_controller.cc
+++ b/ash/wm/splitview/split_view_controller.cc
@@ -4,6 +4,7 @@
 
 #include "ash/wm/splitview/split_view_controller.h"
 
+#include <algorithm>
 #include <cmath>
 #include <memory>
 
@@ -49,7 +50,6 @@
 #include "base/containers/contains.h"
 #include "base/containers/cxx20_erase.h"
 #include "base/containers/flat_set.h"
-#include "base/cxx17_backports.h"
 #include "base/functional/bind.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
@@ -166,10 +166,10 @@
 
 gfx::Point GetBoundedPosition(const gfx::Point& location_in_screen,
                               const gfx::Rect& bounds_in_screen) {
-  return gfx::Point(base::clamp(location_in_screen.x(), bounds_in_screen.x(),
-                                bounds_in_screen.right() - 1),
-                    base::clamp(location_in_screen.y(), bounds_in_screen.y(),
-                                bounds_in_screen.bottom() - 1));
+  return gfx::Point(std::clamp(location_in_screen.x(), bounds_in_screen.x(),
+                               bounds_in_screen.right() - 1),
+                    std::clamp(location_in_screen.y(), bounds_in_screen.y(),
+                               bounds_in_screen.bottom() - 1));
 }
 
 ui::InputMethod* GetCurrentInputMethod() {
diff --git a/ash/wm/tablet_mode/tablet_mode_controller.cc b/ash/wm/tablet_mode/tablet_mode_controller.cc
index c452c33..7bd8535 100644
--- a/ash/wm/tablet_mode/tablet_mode_controller.cc
+++ b/ash/wm/tablet_mode/tablet_mode_controller.cc
@@ -29,7 +29,6 @@
 #include "ash/wm/window_util.h"
 #include "base/command_line.h"
 #include "base/containers/contains.h"
-#include "base/cxx17_backports.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
 #include "base/location.h"
@@ -950,7 +949,7 @@
   // accuracy.
   float largest_hinge_acceleration =
       std::max(std::abs(base_reading.x()), std::abs(lid_reading.x()));
-  float smoothing_ratio = base::clamp(
+  float smoothing_ratio = std::clamp(
       (largest_hinge_acceleration - kHingeVerticalSmoothingStart) /
           (kHingeVerticalSmoothingMaximum - kHingeVerticalSmoothingStart),
       0.0f, 1.0f);
diff --git a/ash/wm/tablet_mode/tablet_mode_multitask_menu.cc b/ash/wm/tablet_mode/tablet_mode_multitask_menu.cc
index 1f43606..8caabc3 100644
--- a/ash/wm/tablet_mode/tablet_mode_multitask_menu.cc
+++ b/ash/wm/tablet_mode/tablet_mode_multitask_menu.cc
@@ -4,6 +4,7 @@
 
 #include "ash/wm/tablet_mode/tablet_mode_multitask_menu.h"
 
+#include <algorithm>
 #include <bit>
 
 #include "ash/public/cpp/shell_window_ids.h"
@@ -16,7 +17,6 @@
 #include "ash/wm/splitview/split_view_controller.h"
 #include "ash/wm/tablet_mode/tablet_mode_multitask_menu_event_handler.h"
 #include "ash/wm/window_state.h"
-#include "base/cxx17_backports.h"
 #include "base/functional/bind.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "chromeos/ui/frame/multitask_menu/multitask_menu_metrics.h"
@@ -346,7 +346,7 @@
   const float max_translation_y =
       -menu_view_->GetPreferredSize().height() - kVerticalPosition;
   const float translated_ratio =
-      base::clamp(current_translation_y / max_translation_y, 0.f, 1.f);
+      std::clamp(current_translation_y / max_translation_y, 0.f, 1.f);
   Animate(/*show=*/translated_ratio <= 0.5f);
 }
 
diff --git a/ash/wm/window_cycle/window_cycle_item_view.cc b/ash/wm/window_cycle/window_cycle_item_view.cc
index c0b4b40..2952f3b4 100644
--- a/ash/wm/window_cycle/window_cycle_item_view.cc
+++ b/ash/wm/window_cycle/window_cycle_item_view.cc
@@ -4,10 +4,11 @@
 
 #include "ash/wm/window_cycle/window_cycle_item_view.h"
 
+#include <algorithm>
+
 #include "ash/shell.h"
 #include "ash/wm/window_cycle/window_cycle_controller.h"
 #include "ash/wm/window_preview_view.h"
-#include "base/cxx17_backports.h"
 #include "ui/accessibility/ax_action_data.h"
 #include "ui/accessibility/ax_enums.mojom.h"
 #include "ui/aura/window.h"
@@ -107,8 +108,8 @@
 
   // Previews should never be narrower than half or wider than double their
   // fixed height.
-  preview_size.set_width(base::clamp(preview_size.width(), kMinPreviewWidthDp,
-                                     kMaxPreviewWidthDp));
+  preview_size.set_width(
+      std::clamp(preview_size.width(), kMinPreviewWidthDp, kMaxPreviewWidthDp));
 
   const int margin = GetInsets().width();
   preview_size.Enlarge(margin, margin + WindowMiniView::kHeaderHeightDp);
diff --git a/ash/wm/window_cycle/window_cycle_view.cc b/ash/wm/window_cycle/window_cycle_view.cc
index 10e158e18..69c58c5 100644
--- a/ash/wm/window_cycle/window_cycle_view.cc
+++ b/ash/wm/window_cycle/window_cycle_view.cc
@@ -4,19 +4,20 @@
 
 #include "ash/wm/window_cycle/window_cycle_view.h"
 
+#include <algorithm>
+
 #include "ash/accessibility/accessibility_controller_impl.h"
 #include "ash/public/cpp/metrics_util.h"
 #include "ash/public/cpp/style/color_provider.h"
 #include "ash/shell.h"
 #include "ash/strings/grit/ash_strings.h"
-#include "ash/style/ash_color_provider.h"
+#include "ash/style/ash_color_id.h"
 #include "ash/style/system_shadow.h"
 #include "ash/style/tab_slider.h"
 #include "ash/style/tab_slider_button.h"
 #include "ash/wm/window_cycle/window_cycle_controller.h"
 #include "ash/wm/window_cycle/window_cycle_item_view.h"
 #include "base/check_op.h"
-#include "base/cxx17_backports.h"
 #include "base/functional/bind.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/time/time.h"
@@ -122,11 +123,14 @@
   layer()->SetName("WindowCycleView");
   layer()->SetMasksToBounds(true);
 
+  const bool is_jellyroll_enabled = chromeos::features::IsJellyrollEnabled();
   SetBackground(views::CreateThemedRoundedRectBackground(
-      cros_tokens::kCrosSysScrim2, kBackgroundCornerRadius));
+      is_jellyroll_enabled ? cros_tokens::kCrosSysScrim2
+                           : static_cast<ui::ColorId>(kColorAshShieldAndBase80),
+      kBackgroundCornerRadius));
   SetBorder(std::make_unique<views::HighlightBorder>(
       kBackgroundCornerRadius,
-      chromeos::features::IsJellyrollEnabled()
+      is_jellyroll_enabled
           ? views::HighlightBorder::Type::kHighlightBorderOnShadow
           : views::HighlightBorder::Type::kHighlightBorder1,
       /*use_light_colors=*/false));
@@ -146,9 +150,8 @@
                             WindowCycleView::kInsideBorderHorizontalPaddingDp,
                             kInsideBorderVerticalPaddingDp,
                             WindowCycleView::kInsideBorderHorizontalPaddingDp),
-          chromeos::features::IsJellyrollEnabled()
-              ? kBetweenChildPaddingDpCrOSNext
-              : kBetweenChildPaddingDp));
+          is_jellyroll_enabled ? kBetweenChildPaddingDpCrOSNext
+                               : kBetweenChildPaddingDp));
   layout->set_cross_axis_alignment(
       views::BoxLayout::CrossAxisAlignment::kStart);
 
@@ -175,7 +178,9 @@
     // Configure the focus ring for the tab slider selector view.
     views::FocusRing::Install(tab_slider_selector_view);
     auto* focus_ring = views::FocusRing::Get(tab_slider_selector_view);
-    focus_ring->SetColorId(cros_tokens::kCrosSysFocusRing);
+    focus_ring->SetColorId(is_jellyroll_enabled ? cros_tokens::kCrosSysFocusRing
+                                                : static_cast<ui::ColorId>(
+                                                      ui::kColorAshFocusRing));
     const float halo_inset = focus_ring->GetHaloThickness() / 2.f + 2;
     focus_ring->SetHaloInset(-halo_inset);
     // Set a pill shaped (fully rounded rect) highlight path to focus ring.
@@ -194,9 +199,7 @@
     no_recent_items_label_->SetHorizontalAlignment(gfx::ALIGN_CENTER);
     no_recent_items_label_->SetVerticalAlignment(gfx::ALIGN_MIDDLE);
 
-    no_recent_items_label_->SetEnabledColor(
-        AshColorProvider::Get()->GetContentLayerColor(
-            AshColorProvider::ContentLayerType::kIconColorSecondary));
+    no_recent_items_label_->SetEnabledColorId(kColorAshIconColorSecondary);
     no_recent_items_label_->SetFontList(
         no_recent_items_label_->font_list()
             .DeriveWithSizeDelta(
@@ -567,12 +570,12 @@
     // However, the container must span the screen, i.e. the maximum x is 0
     // and the minimum for its right boundary is the width of the screen.
     int minimum_x = width() - content_container_bounds.width();
-    x_offset = base::clamp(x_offset, minimum_x, 0);
+    x_offset = std::clamp(x_offset, minimum_x, 0);
 
     // If the user has dragged, offset the container based on how much they
     // have dragged. Cap |horizontal_distance_dragged_| based on the available
     // distance from the container to the left and right boundaries.
-    float clamped_horizontal_distance_dragged = base::clamp(
+    float clamped_horizontal_distance_dragged = std::clamp(
         horizontal_distance_dragged_, static_cast<float>(minimum_x - x_offset),
         static_cast<float>(-x_offset));
     if (horizontal_distance_dragged_ != clamped_horizontal_distance_dragged)
diff --git a/ash/wm/window_mini_view.cc b/ash/wm/window_mini_view.cc
index af92f70..85adef0 100644
--- a/ash/wm/window_mini_view.cc
+++ b/ash/wm/window_mini_view.cc
@@ -7,6 +7,7 @@
 #include <memory>
 #include <utility>
 
+#include "ash/style/ash_color_id.h"
 #include "ash/style/ash_color_provider.h"
 #include "ash/wm/overview/overview_constants.h"
 #include "ash/wm/window_preview_view.h"
@@ -70,8 +71,11 @@
     // Always put the backdrop view under other children.
     backdrop_view_ = AddChildViewAt(std::make_unique<views::View>(), 0);
     backdrop_view_->SetPaintToLayer();
-    backdrop_view_->SetBackground(
-        views::CreateThemedSolidBackground(cros_tokens::kCrosSysScrim));
+    backdrop_view_->SetBackground(views::CreateThemedSolidBackground(
+        chromeos::features::IsJellyrollEnabled()
+            ? cros_tokens::kCrosSysScrim
+            : static_cast<ui::ColorId>(
+                  kColorAshControlBackgroundColorInactive)));
 
     ui::Layer* layer = backdrop_view_->layer();
     layer->SetFillsBoundsOpaquely(false);
@@ -185,7 +189,10 @@
   gfx::Insets header_insets(0);
   if (chromeos::features::IsJellyrollEnabled()) {
     header_view_->SetBackground(views::CreateThemedRoundedRectBackground(
-        cros_tokens::kCrosSysHeader, /*top_radius=*/kWindowMiniViewCornerRadius,
+        chromeos::features::IsJellyrollEnabled()
+            ? cros_tokens::kCrosSysHeader
+            : static_cast<ui::ColorId>(kColorAshShieldAndBase80),
+        /*top_radius=*/kWindowMiniViewCornerRadius,
         /*bottom_radius=*/0, /*for_border_thickness=*/0));
     header_insets = kHeaderInsets;
   }
diff --git a/ash/wm/window_positioning_utils.cc b/ash/wm/window_positioning_utils.cc
index 3163236..54835d6 100644
--- a/ash/wm/window_positioning_utils.cc
+++ b/ash/wm/window_positioning_utils.cc
@@ -18,7 +18,6 @@
 #include "ash/wm/window_state.h"
 #include "ash/wm/window_util.h"
 #include "ash/wm/wm_event.h"
-#include "base/cxx17_backports.h"
 #include "base/notreached.h"
 #include "base/numerics/ranges.h"
 #include "chromeos/ui/wm/features.h"
@@ -46,8 +45,8 @@
   min_axis_length = std::min(min_axis_length, work_area_axis_length);
   // The primary snap size is proportional to |snap_ratio|.
   if (is_primary_snap) {
-    return base::clamp(static_cast<int>(snap_ratio * work_area_axis_length),
-                       min_axis_length, work_area_axis_length);
+    return std::clamp(static_cast<int>(snap_ratio * work_area_axis_length),
+                      min_axis_length, work_area_axis_length);
   }
 
   // The secondary snap size is proportional to the |snap_ratio|, but
@@ -58,8 +57,8 @@
   // `WindowPositioningUtilsTest.SnapBoundsWithOddNumberedScreenWidth`.
   const int empty_space_axis_length =
       static_cast<int>((1 - snap_ratio) * work_area_axis_length);
-  return base::clamp(work_area_axis_length - empty_space_axis_length,
-                     min_axis_length, work_area_axis_length);
+  return std::clamp(work_area_axis_length - empty_space_axis_length,
+                    min_axis_length, work_area_axis_length);
 }
 
 // Return true if the window or one of its ancestor returns true from
diff --git a/base/threading/thread_restrictions.h b/base/threading/thread_restrictions.h
index f37e3cf..8b95d5a 100644
--- a/base/threading/thread_restrictions.h
+++ b/base/threading/thread_restrictions.h
@@ -172,9 +172,6 @@
 class OutputDevice;
 }
 namespace blink {
-class CategorizedWorkerPoolImpl;
-class CategorizedWorkerPoolJob;
-class CategorizedWorkerPool;
 class DiskDataAllocator;
 class IdentifiabilityActiveSampler;
 class RTCVideoDecoderAdapter;
@@ -190,6 +187,9 @@
 }
 }  // namespace blink
 namespace cc {
+class CategorizedWorkerPoolImpl;
+class CategorizedWorkerPoolJob;
+class CategorizedWorkerPool;
 class CompletionEvent;
 class TileTaskManagerImpl;
 }  // namespace cc
@@ -742,13 +742,13 @@
   friend class android_webview::JsSandboxIsolate;
   friend class base::SimpleThread;
   friend class base::internal::GetAppOutputScopedAllowBaseSyncPrimitives;
-  friend class blink::CategorizedWorkerPoolImpl;
-  friend class blink::CategorizedWorkerPoolJob;
   friend class blink::IdentifiabilityActiveSampler;
   friend class blink::SourceStream;
   friend class blink::VideoTrackRecorderImplContextProvider;
   friend class blink::WorkerThread;
   friend class blink::scheduler::NonMainThreadImpl;
+  friend class cc::CategorizedWorkerPoolImpl;
+  friend class cc::CategorizedWorkerPoolJob;
   friend class chrome_cleaner::ResetShortcutsComponent;
   friend class chrome_cleaner::SystemReportComponent;
   friend class content::BrowserMainLoop;
@@ -829,13 +829,13 @@
   friend class base::StackSamplingProfiler;
   friend class base::internal::JobTaskSource;
   friend class base::sequence_manager::internal::TaskQueueImpl;
-  friend class blink::CategorizedWorkerPoolImpl;
-  friend class blink::CategorizedWorkerPoolJob;
-  friend class blink::CategorizedWorkerPool;
   friend class blink::LegacyWebRtcVideoFrameAdapter;
   friend class blink::RTCVideoDecoderAdapter;
   friend class blink::RTCVideoEncoder;
   friend class blink::WebRtcVideoFrameAdapter;
+  friend class cc::CategorizedWorkerPoolImpl;
+  friend class cc::CategorizedWorkerPoolJob;
+  friend class cc::CategorizedWorkerPool;
   friend class cc::TileTaskManagerImpl;
   friend class content::DesktopCaptureDevice;
   friend class content::EmergencyTraceFinalisationCoordinator;
diff --git a/base/win/registry_unittest.cc b/base/win/registry_unittest.cc
index 407d8b82..77bb741d 100644
--- a/base/win/registry_unittest.cc
+++ b/base/win/registry_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <windows.h>
 
+#include <shlobj.h>
 #include <stdint.h>
 
 #include <cstring>
@@ -469,14 +470,28 @@
   const std::wstring foo_software_key_;
 };
 
+class RegistryTestHKLMAdmin : public RegistryTestHKLM {
+ protected:
+  void SetUp() override {
+    if (!IsRedirectorPresent()) {
+      GTEST_SKIP();
+    }
+    if (!::IsUserAnAdmin()) {
+      GTEST_SKIP();
+    }
+    // Clean up any stale registry keys.
+    for (const REGSAM mask : {kNativeViewMask, kRedirectedViewMask}) {
+      RegKey key;
+      key.Open(HKEY_LOCAL_MACHINE, L"Software", KEY_SET_VALUE | mask);
+      key.DeleteKey(kRootKey);
+    }
+  }
+};
+
 // This test requires running as an Administrator as it tests redirected
 // registry writes to HKLM\Software
 // http://msdn.microsoft.com/en-us/library/windows/desktop/aa384253.aspx
-// TODO(wfh): flaky test on Vista.  See http://crbug.com/377917
-TEST_F(RegistryTestHKLM, DISABLED_Wow64RedirectedFromNative) {
-  if (!IsRedirectorPresent())
-    return;
-
+TEST_F(RegistryTestHKLMAdmin, Wow64RedirectedFromNative) {
   RegKey key;
 
   // Test redirected key access from non-redirected.
@@ -516,10 +531,7 @@
   ASSERT_EQ(ERROR_SUCCESS, key.OpenKey(L"Windows", KEY_READ | KEY_WOW64_64KEY));
 }
 
-// TODO(wfh): flaky test on Vista.  See http://crbug.com/377917
-TEST_F(RegistryTestHKLM, DISABLED_Wow64NativeFromRedirected) {
-  if (!IsRedirectorPresent())
-    return;
+TEST_F(RegistryTestHKLMAdmin, Wow64NativeFromRedirected) {
   RegKey key;
 
   // Test non-redirected key access from redirected.
diff --git a/build/config/mac/mac_sdk.gni b/build/config/mac/mac_sdk.gni
index a7f315c3..d3c4e3c 100644
--- a/build/config/mac/mac_sdk.gni
+++ b/build/config/mac/mac_sdk.gni
@@ -38,7 +38,7 @@
   # The SDK version used when making official builds. This is a single exact
   # version, not a minimum. If this version isn't available official builds
   # will fail.
-  mac_sdk_official_version = "13.0"
+  mac_sdk_official_version = "13.3"
 
   # The SDK build version used when making official builds.  This is a single
   # exact version found at "System/Library/CoreServices/SystemVersion.plist"
diff --git a/build/config/rust.gni b/build/config/rust.gni
index 6f05841..9435aa1 100644
--- a/build/config/rust.gni
+++ b/build/config/rust.gni
@@ -190,7 +190,7 @@
 # (see '*_toolchain_supports_platform above') to enable experimentation with
 # other toolchains.
 rust_abi_target = ""
-if (is_linux) {
+if (is_linux || is_chromeos) {
   cpu = current_cpu
   if (cpu == "arm64") {
     cpu = "aarch64"
diff --git a/build/mac_toolchain.py b/build/mac_toolchain.py
index 68c96e259..cd253cd7 100755
--- a/build/mac_toolchain.py
+++ b/build/mac_toolchain.py
@@ -34,12 +34,16 @@
     return plistlib.load(f)
 
 
-# This contains binaries from Xcode 14.0 14B47b along with the macOS 13 SDK
-# (13.0 22A372). To build these packages, see comments in
+# This contains binaries from Xcode 14.3 14E222b along with the macOS 13.3 SDK
+# (13.3 22E245). To build these packages, see comments in
 # build/xcode_binaries.yaml
+# To update the version numbers, open Xcode's "About Xcode" for the first number
+# and run `xcrun --show-sdk-build-version` for the second.
+# To update the _TAG, use the output of the `cipd create` command mentioned in
+# xcode_binaries.yaml.
 
 MAC_BINARIES_LABEL = 'infra_internal/ios/xcode/xcode_binaries/mac-amd64'
-MAC_BINARIES_TAG = '14b47b'
+MAC_BINARIES_TAG = 'ajH0-Cuzzqtyj98qUlsgO1-lepRhXoVVNAjVXDIYHxcC'
 
 # The toolchain will not be downloaded if the minimum OS version is not met. 19
 # is the major version number for macOS 10.15. Xcode 14.0 14B47b only runs on
diff --git a/buildtools/reclient_cfgs/fetch_reclient_cfgs.py b/buildtools/reclient_cfgs/fetch_reclient_cfgs.py
index 0b45446..98c8290 100755
--- a/buildtools/reclient_cfgs/fetch_reclient_cfgs.py
+++ b/buildtools/reclient_cfgs/fetch_reclient_cfgs.py
@@ -17,6 +17,7 @@
 import sys
 
 THIS_DIR = os.path.abspath(os.path.dirname(__file__))
+CHROMIUM_SRC = os.path.abspath(os.path.join(THIS_DIR,'..','..'))
 
 REPROXY_CFG_HEADER = """# AUTOGENERATED FILE - DO NOT EDIT
 # Generated by fetch_reclient_cfgs.py
@@ -26,14 +27,14 @@
 """
 
 def ClangRevision():
-    sys.path.insert(0, os.path.join(THIS_DIR, '..', '..',
+    sys.path.insert(0, os.path.join(CHROMIUM_SRC,
                                     'tools', 'clang', 'scripts'))
     import update
     sys.path.pop(0)
     return update.PACKAGE_VERSION
 
 def NaclRevision():
-    nacl_dir = os.path.join(THIS_DIR, '..', '..', 'native_client')
+    nacl_dir = os.path.join(CHROMIUM_SRC, 'native_client')
     if not os.path.exists(nacl_dir):
       return None
     return subprocess.check_output(
@@ -77,9 +78,14 @@
         return False
     with open(tmpl_path) as f:
       reproxy_cfg_tmpl = string.Template(REPROXY_CFG_HEADER+f.read())
+    scandeps_bin_name = 'scandeps_server'
+    if sys.platform.startswith('win'):
+       scandeps_bin_name += ".exe"
     reproxy_cfg = reproxy_cfg_tmpl.substitute({
       'rbe_instance': rbe_instance,
       'reproxy_cfg_template': reproxy_cfg_template,
+      'scandeps_bin_path':
+        os.path.join(CHROMIUM_SRC, 'buildtools', 'reclient', scandeps_bin_name),
     })
     reproxy_cfg_path = os.path.join(THIS_DIR, 'reproxy.cfg')
     with open(reproxy_cfg_path, 'w') as f:
diff --git a/buildtools/reclient_cfgs/reproxy_cfg_templates/reproxy.cfg.template b/buildtools/reclient_cfgs/reproxy_cfg_templates/reproxy.cfg.template
index 00d4ea0..b2a15910 100644
--- a/buildtools/reclient_cfgs/reproxy_cfg_templates/reproxy.cfg.template
+++ b/buildtools/reclient_cfgs/reproxy_cfg_templates/reproxy.cfg.template
@@ -8,3 +8,5 @@
 # TODO(b/276727504) Re-enable once noop build shutdown time bug is fixed
 # enable_deps_cache=true
 use_unified_uploads=true
+fast_log_collection=true
+depsscanner_address=exec://${scandeps_bin_path}
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index e5f60ae1..05e11fe 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -216,6 +216,8 @@
     "metrics/web_vital_metrics.h",
     "raster/bitmap_raster_buffer_provider.cc",
     "raster/bitmap_raster_buffer_provider.h",
+    "raster/categorized_worker_pool.cc",
+    "raster/categorized_worker_pool.h",
     "raster/gpu_raster_buffer_provider.cc",
     "raster/gpu_raster_buffer_provider.h",
     "raster/lcd_text_disallowed_reason.cc",
@@ -773,6 +775,7 @@
     "paint/skia_paint_canvas_unittest.cc",
     "paint/solid_color_analyzer_unittest.cc",
     "paint/transfer_cache_unittest.cc",
+    "raster/categorized_worker_pool_unittest.cc",
     "raster/playback_image_provider_unittest.cc",
     "raster/raster_buffer_provider_unittest.cc",
     "raster/raster_source_unittest.cc",
diff --git a/cc/base/switches.cc b/cc/base/switches.cc
index ea6c4e80..e071967 100644
--- a/cc/base/switches.cc
+++ b/cc/base/switches.cc
@@ -52,6 +52,9 @@
 const char kDisableLayerTreeHostMemoryPressure[] =
     "disable-layer-tree-host-memory-pressure";
 
+// Controls the number of threads to use for raster tasks.
+const char kNumRasterThreads[] = "num-raster-threads";
+
 // Renders a border around compositor layers to help debug and study
 // layer compositing.
 const char kShowCompositedLayerBorders[] = "show-composited-layer-borders";
diff --git a/cc/base/switches.h b/cc/base/switches.h
index c31d7345..a92bed0 100644
--- a/cc/base/switches.h
+++ b/cc/base/switches.h
@@ -34,6 +34,9 @@
 // Switches for LayerTreeHost.
 CC_BASE_EXPORT extern const char kDisableLayerTreeHostMemoryPressure[];
 
+// Switches for raster.
+CC_BASE_EXPORT extern const char kNumRasterThreads[];
+
 // Debug visualizations.
 CC_BASE_EXPORT extern const char kShowCompositedLayerBorders[];
 CC_BASE_EXPORT extern const char kUIShowCompositedLayerBorders[];
diff --git a/third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool.cc b/cc/raster/categorized_worker_pool.cc
similarity index 77%
rename from third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool.cc
rename to cc/raster/categorized_worker_pool.cc
index 2d2bd97..4a4af53 100644
--- a/third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool.cc
+++ b/cc/raster/categorized_worker_pool.cc
@@ -2,8 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool.h"
+#include "cc/raster/categorized_worker_pool.h"
 
+#include <algorithm>
+#include <memory>
 #include <string>
 #include <utility>
 
@@ -12,6 +14,7 @@
 #include "base/containers/cxx20_erase.h"
 #include "base/feature_list.h"
 #include "base/functional/bind.h"
+#include "base/no_destructor.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/task/sequence_manager/task_time_observer.h"
@@ -23,14 +26,10 @@
 #include "base/trace_event/typed_macros.h"
 #include "build/build_config.h"
 #include "cc/base/math_util.h"
+#include "cc/base/switches.h"
 #include "cc/raster/task_category.h"
-#include "third_party/blink/public/common/switches.h"
-#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/renderer/platform/scheduler/public/main_thread.h"
-#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
-#include "third_party/blink/renderer/platform/wtf/vector.h"
 
-namespace blink {
+namespace cc {
 namespace {
 
 BASE_FEATURE(kUseCompositorJob,
@@ -38,24 +37,24 @@
              base::FEATURE_ENABLED_BY_DEFAULT);
 
 // Task categories running at normal thread priority.
-constexpr cc::TaskCategory kNormalThreadPriorityCategories[] = {
-    cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND, cc::TASK_CATEGORY_FOREGROUND,
-    cc::TASK_CATEGORY_BACKGROUND_WITH_NORMAL_THREAD_PRIORITY};
+constexpr TaskCategory kNormalThreadPriorityCategories[] = {
+    TASK_CATEGORY_NONCONCURRENT_FOREGROUND, TASK_CATEGORY_FOREGROUND,
+    TASK_CATEGORY_BACKGROUND_WITH_NORMAL_THREAD_PRIORITY};
 
 // Task categories running at background thread priority.
-constexpr cc::TaskCategory kBackgroundThreadPriorityCategories[] = {
-    cc::TASK_CATEGORY_BACKGROUND};
+constexpr TaskCategory kBackgroundThreadPriorityCategories[] = {
+    TASK_CATEGORY_BACKGROUND};
 
 // Foreground task categories.
-constexpr cc::TaskCategory kForegroundCategories[] = {
-    cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND, cc::TASK_CATEGORY_FOREGROUND};
+constexpr TaskCategory kForegroundCategories[] = {
+    TASK_CATEGORY_NONCONCURRENT_FOREGROUND, TASK_CATEGORY_FOREGROUND};
 
 // Background task categories. Tasks in these categories cannot start running
 // when a task with a category in |kForegroundCategories| is running or ready to
 // run.
-constexpr cc::TaskCategory kBackgroundCategories[] = {
-    cc::TASK_CATEGORY_BACKGROUND,
-    cc::TASK_CATEGORY_BACKGROUND_WITH_NORMAL_THREAD_PRIORITY};
+constexpr TaskCategory kBackgroundCategories[] = {
+    TASK_CATEGORY_BACKGROUND,
+    TASK_CATEGORY_BACKGROUND_WITH_NORMAL_THREAD_PRIORITY};
 
 // A thread which forwards to CategorizedWorkerPool::Run with the runnable
 // categories.
@@ -65,45 +64,30 @@
       const std::string& name_prefix,
       const Options& options,
       CategorizedWorkerPoolImpl* pool,
-      std::vector<cc::TaskCategory> categories,
+      std::vector<TaskCategory> categories,
       base::ConditionVariable* has_ready_to_run_tasks_cv)
       : SimpleThread(name_prefix, options),
         pool_(pool),
         categories_(categories),
         has_ready_to_run_tasks_cv_(has_ready_to_run_tasks_cv) {}
 
-  void SetBackgroundingCallback(
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
-      base::OnceCallback<void(base::PlatformThreadId)> callback) {
-    DCHECK(!HasStartBeenAttempted());
-    background_task_runner_ = std::move(task_runner);
-    backgrounding_callback_ = std::move(callback);
-  }
-
   // base::SimpleThread:
-  void BeforeRun() override {
-    if (backgrounding_callback_) {
-      DCHECK(background_task_runner_);
-      background_task_runner_->PostTask(
-          FROM_HERE, base::BindOnce(std::move(backgrounding_callback_), tid()));
-      background_task_runner_.reset();
-    }
-  }
+  void BeforeRun() override { pool_->ThreadWillRun(tid()); }
 
   void Run() override { pool_->Run(categories_, has_ready_to_run_tasks_cv_); }
 
  private:
-  CategorizedWorkerPoolImpl* const pool_;
-  const Vector<cc::TaskCategory> categories_;
-  base::ConditionVariable* const has_ready_to_run_tasks_cv_;
+  const raw_ptr<CategorizedWorkerPoolImpl> pool_;
+  const std::vector<TaskCategory> categories_;
+  const raw_ptr<base::ConditionVariable> has_ready_to_run_tasks_cv_;
 
   base::OnceCallback<void(base::PlatformThreadId)> backgrounding_callback_;
   scoped_refptr<base::SingleThreadTaskRunner> background_task_runner_;
 };
 
 scoped_refptr<CategorizedWorkerPool>& GetWorkerPool() {
-  DEFINE_STATIC_LOCAL(scoped_refptr<CategorizedWorkerPool>, worker_pool, ());
-  return worker_pool;
+  static base::NoDestructor<scoped_refptr<CategorizedWorkerPool>> worker_pool;
+  return *worker_pool;
 }
 
 }  // namespace
@@ -113,7 +97,7 @@
     : public base::SequencedTaskRunner {
  public:
   explicit CategorizedWorkerPoolSequencedTaskRunner(
-      cc::TaskGraphRunner* task_graph_runner)
+      TaskGraphRunner* task_graph_runner)
       : task_graph_runner_(task_graph_runner),
         namespace_token_(task_graph_runner->GenerateNamespaceToken()) {}
 
@@ -144,17 +128,18 @@
     graph_.Reset();
     for (const auto& graph_task : tasks_) {
       int dependencies = 0;
-      if (!graph_.nodes.empty())
+      if (!graph_.nodes.empty()) {
         dependencies = 1;
+      }
 
       // Treat any tasks that are enqueued through the SequencedTaskRunner as
       // FOREGROUND priority. We don't have enough information to know the
       // actual priority of such tasks, so we run them as soon as possible.
-      cc::TaskGraph::Node node(graph_task, cc::TASK_CATEGORY_FOREGROUND,
-                               0u /* priority */, dependencies);
+      TaskGraph::Node node(graph_task, TASK_CATEGORY_FOREGROUND,
+                           0u /* priority */, dependencies);
       if (dependencies) {
-        graph_.edges.push_back(cc::TaskGraph::Edge(
-            graph_.nodes.back().task.get(), node.task.get()));
+        graph_.edges.push_back(
+            TaskGraph::Edge(graph_.nodes.back().task.get(), node.task.get()));
       }
       graph_.nodes.push_back(std::move(node));
     }
@@ -179,20 +164,21 @@
   // implement the SequencedTaskRunner interfaces.
   base::Lock lock_;
 
-  cc::TaskGraphRunner* task_graph_runner_;
+  raw_ptr<TaskGraphRunner> task_graph_runner_;
   // Namespace used to schedule tasks in the task graph runner.
-  cc::NamespaceToken namespace_token_;
+  NamespaceToken namespace_token_;
   // List of tasks currently queued up for execution.
-  cc::Task::Vector tasks_;
+  Task::Vector tasks_;
   // Graph object used for scheduling tasks.
-  cc::TaskGraph graph_;
+  TaskGraph graph_;
   // Cached vector to avoid allocation when getting the list of complete
   // tasks.
-  cc::Task::Vector completed_tasks_;
+  Task::Vector completed_tasks_;
 };
 
-CategorizedWorkerPoolImpl::CategorizedWorkerPoolImpl()
-    : has_task_for_normal_priority_thread_cv_(&lock_),
+CategorizedWorkerPoolImpl::CategorizedWorkerPoolImpl(Delegate* delegate)
+    : delegate_(delegate),
+      has_task_for_normal_priority_thread_cv_(&lock_),
       has_task_for_background_priority_thread_cv_(&lock_),
       shutdown_(false) {
   // Declare the two ConditionVariables which are used by worker threads to
@@ -208,13 +194,13 @@
 
   // |max_concurrency_foreground| normal threads and 1 background threads are
   // created.
-  const wtf_size_t num_threads = max_concurrency_foreground + 1;
+  const size_t num_threads = max_concurrency_foreground + 1;
   threads_.reserve(num_threads);
 
   // Start |max_concurrency_foreground| normal priority threads, which run
   // foreground work and background work that cannot run at background thread
   // priority.
-  std::vector<cc::TaskCategory> normal_thread_prio_categories(
+  std::vector<TaskCategory> normal_thread_prio_categories(
       std::begin(kNormalThreadPriorityCategories),
       std::end(kNormalThreadPriorityCategories));
 
@@ -228,7 +214,7 @@
   }
 
   // Start a single thread running at background thread priority.
-  std::vector<cc::TaskCategory> background_thread_prio_categories{
+  std::vector<TaskCategory> background_thread_prio_categories{
       std::begin(kBackgroundThreadPriorityCategories),
       std::end(kBackgroundThreadPriorityCategories)};
 
@@ -242,15 +228,6 @@
       "CompositorTileWorkerBackground", thread_options, this,
       background_thread_prio_categories,
       &has_task_for_background_priority_thread_cv_);
-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
-  thread->SetBackgroundingCallback(
-      Thread::MainThread()->GetTaskRunner(MainThreadTaskRunnerRestricted()),
-      base::BindOnce([](base::PlatformThreadId thread_id) {
-        Platform::Current()->SetThreadType(thread_id,
-                                           base::ThreadType::kBackground);
-      }));
-#endif
-
   thread->StartAsync();
   threads_.push_back(std::move(thread));
 
@@ -284,6 +261,12 @@
   }
 }
 
+void CategorizedWorkerPoolImpl::ThreadWillRun(base::PlatformThreadId tid) {
+  if (delegate_) {
+    delegate_->NotifyThreadWillRun(tid);
+  }
+}
+
 // Overridden from base::TaskRunner:
 bool CategorizedWorkerPoolImpl::PostDelayedTask(const base::Location& from_here,
                                                 base::OnceClosure task,
@@ -294,7 +277,7 @@
   DCHECK(completed_tasks_.empty());
   CollectCompletedTasksWithLockAcquired(namespace_token_, &completed_tasks_);
 
-  base::EraseIf(tasks_, [this](const scoped_refptr<cc::Task>& e)
+  base::EraseIf(tasks_, [this](const scoped_refptr<Task>& e)
                             EXCLUSIVE_LOCKS_REQUIRED(lock_) {
                               return base::Contains(this->completed_tasks_, e);
                             });
@@ -305,8 +288,8 @@
     // Delayed tasks are assigned FOREGROUND category, ensuring that they run as
     // soon as possible once their delay has expired.
     graph_.nodes.push_back(
-        cc::TaskGraph::Node(graph_task.get(), cc::TASK_CATEGORY_FOREGROUND,
-                            0u /* priority */, 0u /* dependencies */));
+        TaskGraph::Node(graph_task.get(), TASK_CATEGORY_FOREGROUND,
+                        0u /* priority */, 0u /* dependencies */));
   }
 
   ScheduleTasksWithLockAcquired(namespace_token_, &graph_);
@@ -315,7 +298,7 @@
 }
 
 void CategorizedWorkerPoolImpl::Run(
-    const Vector<cc::TaskCategory>& categories,
+    const std::vector<TaskCategory>& categories,
     base::ConditionVariable* has_ready_to_run_tasks_cv) {
   base::AutoLock lock(lock_);
 
@@ -331,8 +314,9 @@
       PERFETTO_INTERNAL_ADD_EMPTY_EVENT();
 
       // Exit when shutdown is set and no more tasks are pending.
-      if (shutdown_)
+      if (shutdown_) {
         break;
+      }
 
       // Wait for more tasks.
       has_ready_to_run_tasks_cv->Wait();
@@ -349,8 +333,8 @@
   }
 }
 
-void CategorizedWorkerPoolImpl::ScheduleTasks(cc::NamespaceToken token,
-                                              cc::TaskGraph* graph) {
+void CategorizedWorkerPoolImpl::ScheduleTasks(NamespaceToken token,
+                                              TaskGraph* graph) {
   TRACE_EVENT2("disabled-by-default-cc.debug",
                "CategorizedWorkerPool::ScheduleTasks", "num_nodes",
                graph->nodes.size(), "num_edges", graph->edges.size());
@@ -361,10 +345,10 @@
 }
 
 void CategorizedWorkerPoolImpl::ScheduleTasksWithLockAcquired(
-    cc::NamespaceToken token,
-    cc::TaskGraph* graph) {
+    NamespaceToken token,
+    TaskGraph* graph) {
   DCHECK(token.IsValid());
-  DCHECK(!cc::TaskGraphWorkQueue::DependencyMismatch(graph));
+  DCHECK(!TaskGraphWorkQueue::DependencyMismatch(graph));
   DCHECK(!shutdown_);
 
   work_queue_.ScheduleTasks(token, graph);
@@ -374,7 +358,7 @@
 }
 
 bool CategorizedWorkerPoolImpl::RunTaskWithLockAcquired(
-    const Vector<cc::TaskCategory>& categories) {
+    const std::vector<TaskCategory>& categories) {
   for (const auto& category : categories) {
     if (ShouldRunTaskForCategoryWithLockAcquired(category)) {
       RunTaskInCategoryWithLockAcquired(category);
@@ -385,7 +369,7 @@
 }
 
 void CategorizedWorkerPoolImpl::RunTaskInCategoryWithLockAcquired(
-    cc::TaskCategory category) {
+    TaskCategory category) {
   lock_.AssertAcquired();
 
   auto prioritized_task = work_queue_.GetNextTaskToRun(category);
@@ -408,14 +392,15 @@
   work_queue_.CompleteTask(std::move(prioritized_task));
 
   // If namespace has finished running all tasks, wake up origin threads.
-  if (work_queue_.HasFinishedRunningTasksInNamespace(task_namespace))
+  if (work_queue_.HasFinishedRunningTasksInNamespace(task_namespace)) {
     has_namespaces_with_finished_running_tasks_cv_.Signal();
+  }
 }
 
 void CategorizedWorkerPoolImpl::SignalHasReadyToRunTasksWithLockAcquired() {
   lock_.AssertAcquired();
 
-  for (cc::TaskCategory category : kNormalThreadPriorityCategories) {
+  for (TaskCategory category : kNormalThreadPriorityCategories) {
     if (ShouldRunTaskForCategoryWithLockAcquired(category)) {
       has_task_for_normal_priority_thread_cv_.Signal();
       return;
@@ -424,7 +409,7 @@
 
   // Due to the early return in the previous loop, this only runs when there are
   // no tasks to run on normal priority threads.
-  for (cc::TaskCategory category : kBackgroundThreadPriorityCategories) {
+  for (TaskCategory category : kBackgroundThreadPriorityCategories) {
     if (ShouldRunTaskForCategoryWithLockAcquired(category)) {
       has_task_for_background_priority_thread_cv_.Signal();
       return;
@@ -441,10 +426,9 @@
       FROM_HERE,
       {base::TaskPriority::BEST_EFFORT, base::ThreadPolicy::PREFER_BACKGROUND,
        base::MayBlock()},
-      base::BindRepeating(&CategorizedWorkerPoolJob::Run,
-                          base::Unretained(this),
-                          base::span<const cc::TaskCategory>(
-                              kBackgroundThreadPriorityCategories)),
+      base::BindRepeating(
+          &CategorizedWorkerPoolJob::Run, base::Unretained(this),
+          base::span<const TaskCategory>(kBackgroundThreadPriorityCategories)),
       base::BindRepeating(
           [](CategorizedWorkerPoolJob* self, size_t) {
             return std::min<size_t>(1U,
@@ -456,7 +440,7 @@
       FROM_HERE, {base::TaskPriority::USER_BLOCKING, base::MayBlock()},
       base::BindRepeating(
           &CategorizedWorkerPoolJob::Run, base::Unretained(this),
-          base::span<const cc::TaskCategory>(kNormalThreadPriorityCategories)),
+          base::span<const TaskCategory>(kNormalThreadPriorityCategories)),
       base::BindRepeating(
           [](CategorizedWorkerPoolJob* self, size_t) {
             return std::min(
@@ -480,10 +464,12 @@
     DCHECK(!work_queue_.HasReadyToRunTasks());
     DCHECK(!work_queue_.HasAnyNamespaces());
   }
-  if (foreground_job_handle_)
+  if (foreground_job_handle_) {
     foreground_job_handle_.Cancel();
-  if (background_job_handle_)
+  }
+  if (background_job_handle_) {
     background_job_handle_.Cancel();
+  }
 }
 
 // Overridden from base::TaskRunner:
@@ -499,7 +485,7 @@
     CollectCompletedTasksWithLockAcquired(namespace_token_, &completed_tasks_);
 
     base::EraseIf(tasks_,
-                  [this](const scoped_refptr<cc::Task>& e)
+                  [this](const scoped_refptr<Task>& e)
                       EXCLUSIVE_LOCKS_REQUIRED(lock_) {
                         return base::Contains(this->completed_tasks_, e);
                       });
@@ -510,23 +496,23 @@
       // Delayed tasks are assigned FOREGROUND category, ensuring that they run
       // as soon as possible once their delay has expired.
       graph_.nodes.push_back(
-          cc::TaskGraph::Node(graph_task.get(), cc::TASK_CATEGORY_FOREGROUND,
-                              0u /* priority */, 0u /* dependencies */));
+          TaskGraph::Node(graph_task.get(), TASK_CATEGORY_FOREGROUND,
+                          0u /* priority */, 0u /* dependencies */));
     }
 
     job_handle_to_notify =
         ScheduleTasksWithLockAcquired(namespace_token_, &graph_);
     completed_tasks_.clear();
   }
-  if (job_handle_to_notify)
+  if (job_handle_to_notify) {
     job_handle_to_notify->NotifyConcurrencyIncrease();
+  }
   return true;
 }
 
-void CategorizedWorkerPoolJob::Run(
-    base::span<const cc::TaskCategory> categories,
-    base::JobDelegate* job_delegate) {
-  absl::optional<cc::TaskGraphWorkQueue::PrioritizedTask> prioritized_task;
+void CategorizedWorkerPoolJob::Run(base::span<const TaskCategory> categories,
+                                   base::JobDelegate* job_delegate) {
+  absl::optional<TaskGraphWorkQueue::PrioritizedTask> prioritized_task;
 
   while (!job_delegate->ShouldYield()) {
     base::JobHandle* job_handle_to_notify = nullptr;
@@ -541,12 +527,14 @@
             ScheduleTasksWithLockAcquired(namespace_token_, &graph_);
       }
     }
-    if (job_handle_to_notify)
+    if (job_handle_to_notify) {
       job_handle_to_notify->NotifyConcurrencyIncrease();
+    }
 
     // There's no pending task to run, quit the worker until notified again.
-    if (!prioritized_task)
+    if (!prioritized_task) {
       return;
+    }
     TRACE_EVENT(
         "toplevel", "TaskGraphRunner::RunTask",
         [&](perfetto::EventContext ctx) {
@@ -565,15 +553,16 @@
       work_queue_.CompleteTask(std::move(*prioritized_task));
 
       // If namespace has finished running all tasks, wake up origin threads.
-      if (work_queue_.HasFinishedRunningTasksInNamespace(task_namespace))
+      if (work_queue_.HasFinishedRunningTasksInNamespace(task_namespace)) {
         has_namespaces_with_finished_running_tasks_cv_.Signal();
+      }
     }
   }
 }
 
-absl::optional<cc::TaskGraphWorkQueue::PrioritizedTask>
+absl::optional<TaskGraphWorkQueue::PrioritizedTask>
 CategorizedWorkerPoolJob::GetNextTaskToRunWithLockAcquired(
-    base::span<const cc::TaskCategory> categories) {
+    base::span<const TaskCategory> categories) {
   lock_.AssertAcquired();
   for (const auto& category : categories) {
     if (ShouldRunTaskForCategoryWithLockAcquired(category)) {
@@ -588,8 +577,8 @@
   background_job_handle_.Join();
 }
 
-void CategorizedWorkerPoolJob::ScheduleTasks(cc::NamespaceToken token,
-                                             cc::TaskGraph* graph) {
+void CategorizedWorkerPoolJob::ScheduleTasks(NamespaceToken token,
+                                             TaskGraph* graph) {
   TRACE_EVENT2("disabled-by-default-cc.debug",
                "CategorizedWorkerPool::ScheduleTasks", "num_nodes",
                graph->nodes.size(), "num_edges", graph->edges.size());
@@ -598,15 +587,16 @@
     base::AutoLock lock(lock_);
     job_handle_to_notify = ScheduleTasksWithLockAcquired(token, graph);
   }
-  if (job_handle_to_notify)
+  if (job_handle_to_notify) {
     job_handle_to_notify->NotifyConcurrencyIncrease();
+  }
 }
 
 base::JobHandle* CategorizedWorkerPoolJob::ScheduleTasksWithLockAcquired(
-    cc::NamespaceToken token,
-    cc::TaskGraph* graph) {
+    NamespaceToken token,
+    TaskGraph* graph) {
   DCHECK(token.IsValid());
-  DCHECK(!cc::TaskGraphWorkQueue::DependencyMismatch(graph));
+  DCHECK(!TaskGraphWorkQueue::DependencyMismatch(graph));
 
   work_queue_.ScheduleTasks(token, graph);
   return GetJobHandleToNotifyWithLockAcquired();
@@ -616,7 +606,7 @@
 CategorizedWorkerPoolJob::GetJobHandleToNotifyWithLockAcquired() {
   lock_.AssertAcquired();
 
-  for (cc::TaskCategory category : kNormalThreadPriorityCategories) {
+  for (TaskCategory category : kNormalThreadPriorityCategories) {
     if (ShouldRunTaskForCategoryWithLockAcquired(category)) {
       return &foreground_job_handle_;
     }
@@ -624,7 +614,7 @@
 
   // Due to the early return in the previous loop, this only runs when there are
   // no tasks to run on normal priority threads.
-  for (cc::TaskCategory category : kBackgroundThreadPriorityCategories) {
+  for (TaskCategory category : kBackgroundThreadPriorityCategories) {
     if (ShouldRunTaskForCategoryWithLockAcquired(category)) {
       return &background_job_handle_;
     }
@@ -633,11 +623,11 @@
 }
 
 size_t CategorizedWorkerPoolJob::GetMaxJobConcurrency(
-    base::span<const cc::TaskCategory> categories) const {
+    base::span<const TaskCategory> categories) const {
   base::AutoLock lock(lock_);
 
   bool has_foreground_tasks = false;
-  for (cc::TaskCategory foreground_category : kForegroundCategories) {
+  for (TaskCategory foreground_category : kForegroundCategories) {
     if (work_queue_.NumRunningTasksForCategory(foreground_category) > 0 ||
         work_queue_.HasReadyToRunTasksForCategory(foreground_category)) {
       has_foreground_tasks = true;
@@ -646,28 +636,30 @@
   }
 
   bool has_running_background_tasks = false;
-  for (cc::TaskCategory background_category : kBackgroundCategories) {
+  for (TaskCategory background_category : kBackgroundCategories) {
     has_running_background_tasks |=
         work_queue_.NumRunningTasksForCategory(background_category);
   }
 
   size_t num_foreground_tasks = 0;
   size_t num_background_tasks = 0;
-  for (cc::TaskCategory category : categories) {
+  for (TaskCategory category : categories) {
     if (base::Contains(kBackgroundCategories, category)) {
-      if (work_queue_.NumRunningTasksForCategory(category) > 0)
+      if (work_queue_.NumRunningTasksForCategory(category) > 0) {
         num_background_tasks = 1;
+      }
       // Enforce that only one background task is allowed to run at a time, and
       // only if there are no foreground tasks running or ready to run.
       if (!has_running_background_tasks && !has_foreground_tasks &&
           work_queue_.HasReadyToRunTasksForCategory(category)) {
         num_background_tasks = 1;
       }
-    } else if (category == cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND) {
+    } else if (category == TASK_CATEGORY_NONCONCURRENT_FOREGROUND) {
       // Enforce that only one nonconcurrent task is allowed to run at a time.
       if (work_queue_.NumRunningTasksForCategory(category) > 0 ||
-          work_queue_.HasReadyToRunTasksForCategory(category))
+          work_queue_.HasReadyToRunTasksForCategory(category)) {
         ++num_foreground_tasks;
+      }
     } else {
       num_foreground_tasks += work_queue_.NumRunningTasksForCategory(category) +
                               work_queue_.NumReadyTasksForCategory(category);
@@ -676,9 +668,10 @@
   return num_foreground_tasks + num_background_tasks;
 }
 
-CategorizedWorkerPool* CategorizedWorkerPool::GetOrCreate() {
-  if (GetWorkerPool())
+CategorizedWorkerPool* CategorizedWorkerPool::GetOrCreate(Delegate* delegate) {
+  if (GetWorkerPool()) {
     return GetWorkerPool().get();
+  }
 
   const base::CommandLine& command_line =
       *base::CommandLine::ForCurrentProcess();
@@ -696,7 +689,7 @@
       base::FeatureList::IsEnabled(kUseCompositorJob)
           ? scoped_refptr<CategorizedWorkerPool>(new CategorizedWorkerPoolJob())
           : scoped_refptr<CategorizedWorkerPool>(
-                new CategorizedWorkerPoolImpl());
+                new CategorizedWorkerPoolImpl(delegate));
   categorized_worker_pool->Start(num_raster_threads);
   GetWorkerPool() = std::move(categorized_worker_pool);
   return GetWorkerPool().get();
@@ -713,13 +706,12 @@
 
 CategorizedWorkerPool::~CategorizedWorkerPool() = default;
 
-cc::NamespaceToken CategorizedWorkerPool::GenerateNamespaceToken() {
+NamespaceToken CategorizedWorkerPool::GenerateNamespaceToken() {
   base::AutoLock lock(lock_);
   return work_queue_.GenerateNamespaceToken();
 }
 
-void CategorizedWorkerPool::WaitForTasksToFinishRunning(
-    cc::NamespaceToken token) {
+void CategorizedWorkerPool::WaitForTasksToFinishRunning(NamespaceToken token) {
   TRACE_EVENT0("disabled-by-default-cc.debug",
                "CategorizedWorkerPool::WaitForTasksToFinishRunning");
 
@@ -730,11 +722,13 @@
 
     auto* task_namespace = work_queue_.GetNamespaceForToken(token);
 
-    if (!task_namespace)
+    if (!task_namespace) {
       return;
+    }
 
-    while (!work_queue_.HasFinishedRunningTasksInNamespace(task_namespace))
+    while (!work_queue_.HasFinishedRunningTasksInNamespace(task_namespace)) {
       has_namespaces_with_finished_running_tasks_cv_.Wait();
+    }
 
     // There may be other namespaces that have finished running tasks, so wake
     // up another origin thread.
@@ -743,8 +737,8 @@
 }
 
 void CategorizedWorkerPool::CollectCompletedTasks(
-    cc::NamespaceToken token,
-    cc::Task::Vector* completed_tasks) {
+    NamespaceToken token,
+    Task::Vector* completed_tasks) {
   TRACE_EVENT0("disabled-by-default-cc.debug",
                "CategorizedWorkerPool::CollectCompletedTasks");
 
@@ -755,23 +749,24 @@
 }
 
 void CategorizedWorkerPool::CollectCompletedTasksWithLockAcquired(
-    cc::NamespaceToken token,
-    cc::Task::Vector* completed_tasks) {
+    NamespaceToken token,
+    Task::Vector* completed_tasks) {
   DCHECK(token.IsValid());
   work_queue_.CollectCompletedTasks(token, completed_tasks);
 }
 
 bool CategorizedWorkerPool::ShouldRunTaskForCategoryWithLockAcquired(
-    cc::TaskCategory category) {
+    TaskCategory category) {
   lock_.AssertAcquired();
 
-  if (!work_queue_.HasReadyToRunTasksForCategory(category))
+  if (!work_queue_.HasReadyToRunTasksForCategory(category)) {
     return false;
+  }
 
   if (base::Contains(kBackgroundCategories, category)) {
     // Only run background tasks if there are no foreground tasks running or
     // ready to run.
-    for (cc::TaskCategory foreground_category : kForegroundCategories) {
+    for (TaskCategory foreground_category : kForegroundCategories) {
       if (work_queue_.NumRunningTasksForCategory(foreground_category) > 0 ||
           work_queue_.HasReadyToRunTasksForCategory(foreground_category)) {
         return false;
@@ -779,16 +774,17 @@
     }
 
     // Enforce that only one background task runs at a time.
-    for (cc::TaskCategory background_category : kBackgroundCategories) {
-      if (work_queue_.NumRunningTasksForCategory(background_category) > 0)
+    for (TaskCategory background_category : kBackgroundCategories) {
+      if (work_queue_.NumRunningTasksForCategory(background_category) > 0) {
         return false;
+      }
     }
   }
 
   // Enforce that only one nonconcurrent task runs at a time.
-  if (category == cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND &&
+  if (category == TASK_CATEGORY_NONCONCURRENT_FOREGROUND &&
       work_queue_.NumRunningTasksForCategory(
-          cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND) > 0) {
+          TASK_CATEGORY_NONCONCURRENT_FOREGROUND) > 0) {
     return false;
   }
 
@@ -798,11 +794,11 @@
 CategorizedWorkerPool::ClosureTask::ClosureTask(base::OnceClosure closure)
     : closure_(std::move(closure)) {}
 
-// Overridden from cc::Task:
+// Overridden from Task:
 void CategorizedWorkerPool::ClosureTask::RunOnWorkerThread() {
   std::move(closure_).Run();
 }
 
 CategorizedWorkerPool::ClosureTask::~ClosureTask() {}
 
-}  // namespace blink
+}  // namespace cc
diff --git a/third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool.h b/cc/raster/categorized_worker_pool.h
similarity index 65%
rename from third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool.h
rename to cc/raster/categorized_worker_pool.h
index 3a1bc24..3334497e 100644
--- a/third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool.h
+++ b/cc/raster/categorized_worker_pool.h
@@ -2,25 +2,29 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_COMPOSITING_CATEGORIZED_WORKER_POOL_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_COMPOSITING_CATEGORIZED_WORKER_POOL_H_
+#ifndef CC_RASTER_CATEGORIZED_WORKER_POOL_H_
+#define CC_RASTER_CATEGORIZED_WORKER_POOL_H_
+
+#include <memory>
+#include <vector>
 
 #include "base/containers/span.h"
 #include "base/functional/callback.h"
+#include "base/memory/raw_ptr.h"
 #include "base/synchronization/condition_variable.h"
 #include "base/task/post_job.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/task/task_runner.h"
 #include "base/thread_annotations.h"
+#include "base/threading/platform_thread.h"
 #include "base/threading/simple_thread.h"
+#include "cc/cc_export.h"
 #include "cc/raster/task_category.h"
 #include "cc/raster/task_graph_runner.h"
 #include "cc/raster/task_graph_work_queue.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/vector.h"
 
-namespace blink {
+namespace cc {
 
 // A pool of threads used to run categorized work. The work can be scheduled on
 // the threads using different interfaces.
@@ -30,20 +34,29 @@
 //    schedule a graph of tasks with their dependencies.
 // 3. CreateSequencedTaskRunner() creates a sequenced task runner that might run
 //    in parallel with other instances of sequenced task runners.
-class PLATFORM_EXPORT CategorizedWorkerPool : public base::TaskRunner,
-                                              public cc::TaskGraphRunner {
+class CC_EXPORT CategorizedWorkerPool : public base::TaskRunner,
+                                        public TaskGraphRunner {
  public:
+  class CC_EXPORT Delegate {
+   public:
+    virtual ~Delegate() = default;
+
+    // Called on the delegate with a worker pool thread ID as soon as the
+    // thread is created.
+    virtual void NotifyThreadWillRun(base::PlatformThreadId tid) = 0;
+  };
+
   CategorizedWorkerPool();
-  ~CategorizedWorkerPool() override;
 
-  // Get or create the singleton worker pool.
-  static CategorizedWorkerPool* GetOrCreate();
+  // Get or create the singleton worker pool. This object lives forever. If
+  // `delegate` is non-null, it must also live forever.
+  static CategorizedWorkerPool* GetOrCreate(Delegate* delegate = nullptr);
 
-  // Overridden from cc::TaskGraphRunner:
-  cc::NamespaceToken GenerateNamespaceToken() override;
-  void WaitForTasksToFinishRunning(cc::NamespaceToken token) override;
-  void CollectCompletedTasks(cc::NamespaceToken token,
-                             cc::Task::Vector* completed_tasks) override;
+  // Overridden from TaskGraphRunner:
+  NamespaceToken GenerateNamespaceToken() override;
+  void WaitForTasksToFinishRunning(NamespaceToken token) override;
+  void CollectCompletedTasks(NamespaceToken token,
+                             Task::Vector* completed_tasks) override;
 
   virtual void FlushForTesting() = 0;
 
@@ -55,7 +68,7 @@
   // terminated.
   virtual void Shutdown() = 0;
 
-  cc::TaskGraphRunner* GetTaskGraphRunner() { return this; }
+  TaskGraphRunner* GetTaskGraphRunner() { return this; }
 
   // Create a new sequenced task graph runner.
   scoped_refptr<base::SequencedTaskRunner> CreateSequencedTaskRunner();
@@ -64,17 +77,19 @@
   class CategorizedWorkerPoolSequencedTaskRunner;
   friend class CategorizedWorkerPoolSequencedTaskRunner;
 
+  ~CategorizedWorkerPool() override;
+
   // Simple Task for the TaskGraphRunner that wraps a closure.
   // This class is used to schedule TaskRunner tasks on the
   // |task_graph_runner_|.
-  class ClosureTask : public cc::Task {
+  class ClosureTask : public Task {
    public:
     explicit ClosureTask(base::OnceClosure closure);
 
     ClosureTask(const ClosureTask&) = delete;
     ClosureTask& operator=(const ClosureTask&) = delete;
 
-    // Overridden from cc::Task:
+    // Overridden from Task:
     void RunOnWorkerThread() override;
 
    protected:
@@ -84,51 +99,52 @@
     base::OnceClosure closure_;
   };
 
-  void CollectCompletedTasksWithLockAcquired(cc::NamespaceToken token,
-                                             cc::Task::Vector* completed_tasks)
+  void CollectCompletedTasksWithLockAcquired(NamespaceToken token,
+                                             Task::Vector* completed_tasks)
       EXCLUSIVE_LOCKS_REQUIRED(lock_);
 
   // Determines if we should run a new task for the given category. This factors
   // in whether a task is available and whether the count of running tasks is
   // low enough to start a new one.
-  bool ShouldRunTaskForCategoryWithLockAcquired(cc::TaskCategory category)
+  bool ShouldRunTaskForCategoryWithLockAcquired(TaskCategory category)
       EXCLUSIVE_LOCKS_REQUIRED(lock_);
 
   // Lock to exclusively access all the following members that are used to
   // implement the TaskRunner and TaskGraphRunner interfaces.
   mutable base::Lock lock_;
   // Stores the tasks to be run, sorted by priority.
-  cc::TaskGraphWorkQueue work_queue_ GUARDED_BY(lock_);
+  TaskGraphWorkQueue work_queue_ GUARDED_BY(lock_);
   // Namespace used to schedule tasks in the task graph runner.
-  const cc::NamespaceToken namespace_token_;
+  const NamespaceToken namespace_token_;
   // List of tasks currently queued up for execution.
-  cc::Task::Vector tasks_ GUARDED_BY(lock_);
+  Task::Vector tasks_ GUARDED_BY(lock_);
   // Graph object used for scheduling tasks.
-  cc::TaskGraph graph_ GUARDED_BY(lock_);
+  TaskGraph graph_ GUARDED_BY(lock_);
   // Cached vector to avoid allocation when getting the list of complete
   // tasks.
-  cc::Task::Vector completed_tasks_ GUARDED_BY(lock_);
+  Task::Vector completed_tasks_ GUARDED_BY(lock_);
   // Condition variable that is waited on by origin threads until a namespace
   // has finished running all associated tasks.
   base::ConditionVariable has_namespaces_with_finished_running_tasks_cv_;
 };
 
-class PLATFORM_EXPORT CategorizedWorkerPoolImpl : public CategorizedWorkerPool {
+class CC_EXPORT CategorizedWorkerPoolImpl : public CategorizedWorkerPool {
  public:
-  CategorizedWorkerPoolImpl();
-  ~CategorizedWorkerPoolImpl() override;
+  explicit CategorizedWorkerPoolImpl(Delegate* delegate = nullptr);
+
+  void ThreadWillRun(base::PlatformThreadId tid);
 
   // Overridden from base::TaskRunner:
   bool PostDelayedTask(const base::Location& from_here,
                        base::OnceClosure task,
                        base::TimeDelta delay) override;
 
-  // Overridden from cc::TaskGraphRunner:
-  void ScheduleTasks(cc::NamespaceToken token, cc::TaskGraph* graph) override;
+  // Overridden from TaskGraphRunner:
+  void ScheduleTasks(NamespaceToken token, TaskGraph* graph) override;
 
   // Runs a task from one of the provided categories. Categories listed first
   // have higher priority.
-  void Run(const Vector<cc::TaskCategory>& categories,
+  void Run(const std::vector<TaskCategory>& categories,
            base::ConditionVariable* has_ready_to_run_tasks_cv);
 
   // Overridden from CategorizedWorkerPool:
@@ -137,25 +153,28 @@
   void Shutdown() override;
 
  private:
-  void ScheduleTasksWithLockAcquired(cc::NamespaceToken token,
-                                     cc::TaskGraph* graph)
+  ~CategorizedWorkerPoolImpl() override;
+
+  void ScheduleTasksWithLockAcquired(NamespaceToken token, TaskGraph* graph)
       EXCLUSIVE_LOCKS_REQUIRED(lock_);
   // Runs a task from one of the provided categories. Categories listed first
   // have higher priority. Returns false if there were no tasks to run.
-  bool RunTaskWithLockAcquired(const Vector<cc::TaskCategory>& categories)
+  bool RunTaskWithLockAcquired(const std::vector<TaskCategory>& categories)
       EXCLUSIVE_LOCKS_REQUIRED(lock_);
 
   // Run next task for the given category. Caller must acquire |lock_| prior to
   // calling this function and make sure at least one task is ready to run.
-  void RunTaskInCategoryWithLockAcquired(cc::TaskCategory category)
+  void RunTaskInCategoryWithLockAcquired(TaskCategory category)
       EXCLUSIVE_LOCKS_REQUIRED(lock_);
 
   // Helper function which signals worker threads if tasks are ready to run.
   void SignalHasReadyToRunTasksWithLockAcquired()
       EXCLUSIVE_LOCKS_REQUIRED(lock_);
 
+  const raw_ptr<Delegate> delegate_;
+
   // The actual threads where work is done.
-  Vector<std::unique_ptr<base::SimpleThread>> threads_;
+  std::vector<std::unique_ptr<base::SimpleThread>> threads_;
 
   // Condition variables for foreground and background threads.
   base::ConditionVariable has_task_for_normal_priority_thread_cv_;
@@ -165,22 +184,21 @@
   bool shutdown_ GUARDED_BY(lock_);
 };
 
-class PLATFORM_EXPORT CategorizedWorkerPoolJob : public CategorizedWorkerPool {
+class CC_EXPORT CategorizedWorkerPoolJob : public CategorizedWorkerPool {
  public:
   CategorizedWorkerPoolJob();
-  ~CategorizedWorkerPoolJob() override;
 
   // Overridden from base::TaskRunner:
   bool PostDelayedTask(const base::Location& from_here,
                        base::OnceClosure task,
                        base::TimeDelta delay) override;
 
-  // Overridden from cc::TaskGraphRunner:
-  void ScheduleTasks(cc::NamespaceToken token, cc::TaskGraph* graph) override;
+  // Overridden from TaskGraphRunner:
+  void ScheduleTasks(NamespaceToken token, TaskGraph* graph) override;
 
   // Runs a task from one of the provided categories. Categories listed first
   // have higher priority.
-  void Run(base::span<const cc::TaskCategory> categories,
+  void Run(base::span<const TaskCategory> categories,
            base::JobDelegate* job_delegate);
 
   // Overridden from CategorizedWorkerPool:
@@ -189,20 +207,20 @@
   void Shutdown() override;
 
  private:
-  absl::optional<cc::TaskGraphWorkQueue::PrioritizedTask>
-  GetNextTaskToRunWithLockAcquired(
-      base::span<const cc::TaskCategory> categories);
+  ~CategorizedWorkerPoolJob() override;
 
-  base::JobHandle* ScheduleTasksWithLockAcquired(cc::NamespaceToken token,
-                                                 cc::TaskGraph* graph)
+  absl::optional<TaskGraphWorkQueue::PrioritizedTask>
+  GetNextTaskToRunWithLockAcquired(base::span<const TaskCategory> categories);
+
+  base::JobHandle* ScheduleTasksWithLockAcquired(NamespaceToken token,
+                                                 TaskGraph* graph)
       EXCLUSIVE_LOCKS_REQUIRED(lock_);
 
   // Helper function which signals worker threads if tasks are ready to run.
   base::JobHandle* GetJobHandleToNotifyWithLockAcquired()
       EXCLUSIVE_LOCKS_REQUIRED(lock_);
 
-  size_t GetMaxJobConcurrency(
-      base::span<const cc::TaskCategory> categories) const;
+  size_t GetMaxJobConcurrency(base::span<const TaskCategory> categories) const;
 
   size_t max_concurrency_foreground_ = 0;
 
@@ -210,6 +228,6 @@
   base::JobHandle foreground_job_handle_;
 };
 
-}  // namespace blink
+}  // namespace cc
 
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_COMPOSITING_CATEGORIZED_WORKER_POOL_H_
+#endif  // CC_RASTER_CATEGORIZED_WORKER_POOL_H_
diff --git a/third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool_unittest.cc b/cc/raster/categorized_worker_pool_unittest.cc
similarity index 68%
rename from third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool_unittest.cc
rename to cc/raster/categorized_worker_pool_unittest.cc
index fa6d1f0..b54bc123 100644
--- a/third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool_unittest.cc
+++ b/cc/raster/categorized_worker_pool_unittest.cc
@@ -2,18 +2,20 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool.h"
+#include "cc/raster/categorized_worker_pool.h"
+
+#include <utility>
+
+#include "base/functional/callback.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/test/bind.h"
 #include "base/test/sequenced_task_runner_test_template.h"
-#include "base/test/task_environment.h"
 #include "base/test/task_runner_test_template.h"
 #include "base/threading/platform_thread.h"
 #include "base/threading/simple_thread.h"
 #include "cc/test/task_graph_runner_test_template.h"
-#include "third_party/blink/public/platform/platform.h"
 
-namespace blink {
+namespace cc {
 namespace {
 
 // Number of threads spawned in tests.
@@ -35,7 +37,6 @@
   ~CategorizedWorkerPoolTestDelegate() { categorized_worker_pool_->Shutdown(); }
 
  private:
-  base::test::TaskEnvironment task_environment_;
   scoped_refptr<CategorizedWorkerPool> categorized_worker_pool_ =
       base::MakeRefCounted<T>();
 };
@@ -58,7 +59,6 @@
   }
 
  private:
-  base::test::TaskEnvironment task_environment_;
   scoped_refptr<CategorizedWorkerPool> categorized_worker_pool_ =
       base::MakeRefCounted<T>();
 };
@@ -70,7 +70,7 @@
 
   void StartTaskGraphRunner() { categorized_worker_pool_->Start(kNumThreads); }
 
-  cc::TaskGraphRunner* GetTaskGraphRunner() {
+  TaskGraphRunner* GetTaskGraphRunner() {
     return categorized_worker_pool_->GetTaskGraphRunner();
   }
 
@@ -81,7 +81,6 @@
   }
 
  private:
-  base::test::TaskEnvironment task_environment_;
   scoped_refptr<CategorizedWorkerPool> categorized_worker_pool_ =
       base::MakeRefCounted<T>();
 };
@@ -102,18 +101,17 @@
   }
 
   void TearDown() override {
-    cc::Task::Vector completed_tasks;
+    Task::Vector completed_tasks;
     categorized_worker_pool_->CollectCompletedTasks(namespace_token_,
                                                     &completed_tasks);
     categorized_worker_pool_->Shutdown();
   }
 
-  base::test::TaskEnvironment task_environment_;
   scoped_refptr<CategorizedWorkerPool> categorized_worker_pool_;
-  cc::NamespaceToken namespace_token_;
+  NamespaceToken namespace_token_;
 };
 
-class ClosureTask : public cc::Task {
+class ClosureTask : public Task {
  public:
   explicit ClosureTask(base::OnceClosure closure)
       : closure_(std::move(closure)) {}
@@ -121,7 +119,7 @@
   ClosureTask(const ClosureTask&) = delete;
   ClosureTask& operator=(const ClosureTask&) = delete;
 
-  // Overridden from cc::Task:
+  // Overridden from Task:
   void RunOnWorkerThread() override { std::move(closure_).Run(); }
 
  protected:
@@ -137,8 +135,8 @@
 // TASK_CATEGORY_BACKGROUND_WITH_NORMAL_THREAD_PRIORITY don't run
 // concurrently.
 TEST_P(CategorizedWorkerPoolTest, BackgroundTasksDontRunConcurrently) {
-  cc::Task::Vector tasks;
-  cc::TaskGraph graph;
+  Task::Vector tasks;
+  TaskGraph graph;
   bool is_running_task = false;
 
   for (size_t i = 0; i < 100; ++i) {
@@ -152,10 +150,10 @@
           is_running_task = false;
         })));
 
-    graph.nodes.push_back(cc::TaskGraph::Node(
+    graph.nodes.push_back(TaskGraph::Node(
         tasks.back(),
-        i % 2 == 0 ? cc::TASK_CATEGORY_BACKGROUND
-                   : cc::TASK_CATEGORY_BACKGROUND_WITH_NORMAL_THREAD_PRIORITY,
+        i % 2 == 0 ? TASK_CATEGORY_BACKGROUND
+                   : TASK_CATEGORY_BACKGROUND_WITH_NORMAL_THREAD_PRIORITY,
         /* priority=*/0u, /* dependencies=*/0u));
   }
 
@@ -168,15 +166,15 @@
 // doesn't run at background thread priority.
 TEST_P(CategorizedWorkerPoolTest,
        AcquiresForegroundResourcesNotBackgroundThreadPriority) {
-  cc::Task::Vector tasks;
-  cc::TaskGraph graph;
+  Task::Vector tasks;
+  TaskGraph graph;
 
   tasks.push_back(base::MakeRefCounted<ClosureTask>(base::BindOnce([]() {
     EXPECT_NE(base::ThreadType::kBackground,
               base::PlatformThread::GetCurrentThreadType());
   })));
-  graph.nodes.push_back(cc::TaskGraph::Node(
-      tasks.back(), cc::TASK_CATEGORY_BACKGROUND_WITH_NORMAL_THREAD_PRIORITY,
+  graph.nodes.push_back(TaskGraph::Node(
+      tasks.back(), TASK_CATEGORY_BACKGROUND_WITH_NORMAL_THREAD_PRIORITY,
       /* priority=*/0u, /* dependencies=*/0u));
 
   categorized_worker_pool_->ScheduleTasks(namespace_token_, &graph);
@@ -188,7 +186,7 @@
                          CategorizedWorkerPoolTest,
                          testing::Values(false, true));
 
-}  // namespace blink
+}  // namespace cc
 
 // Test suite instantiation needs to be in the same namespace as test suite
 // definition.
@@ -198,22 +196,20 @@
 INSTANTIATE_TYPED_TEST_SUITE_P(
     CategorizedWorkerPoolImpl,
     TaskRunnerTest,
-    blink::CategorizedWorkerPoolTestDelegate<blink::CategorizedWorkerPoolImpl>);
+    cc::CategorizedWorkerPoolTestDelegate<cc::CategorizedWorkerPoolImpl>);
 INSTANTIATE_TYPED_TEST_SUITE_P(
     CategorizedWorkerPoolJob,
     TaskRunnerTest,
-    blink::CategorizedWorkerPoolTestDelegate<blink::CategorizedWorkerPoolJob>);
+    cc::CategorizedWorkerPoolTestDelegate<cc::CategorizedWorkerPoolJob>);
 
-INSTANTIATE_TYPED_TEST_SUITE_P(
-    CategorizedWorkerPoolImpl,
-    SequencedTaskRunnerTest,
-    blink::CategorizedWorkerPoolSequencedTestDelegate<
-        blink::CategorizedWorkerPoolImpl>);
-INSTANTIATE_TYPED_TEST_SUITE_P(
-    CategorizedWorkerPoolJob,
-    SequencedTaskRunnerTest,
-    blink::CategorizedWorkerPoolSequencedTestDelegate<
-        blink::CategorizedWorkerPoolJob>);
+INSTANTIATE_TYPED_TEST_SUITE_P(CategorizedWorkerPoolImpl,
+                               SequencedTaskRunnerTest,
+                               cc::CategorizedWorkerPoolSequencedTestDelegate<
+                                   cc::CategorizedWorkerPoolImpl>);
+INSTANTIATE_TYPED_TEST_SUITE_P(CategorizedWorkerPoolJob,
+                               SequencedTaskRunnerTest,
+                               cc::CategorizedWorkerPoolSequencedTestDelegate<
+                                   cc::CategorizedWorkerPoolJob>);
 
 }  // namespace base
 
@@ -221,20 +217,20 @@
 
 // Multithreaded tests.
 using CategorizedWorkerPoolImplTaskGraphRunnerTestDelegate_1_5 =
-    ::testing::Types<blink::CategorizedWorkerPoolTaskGraphRunnerTestDelegate<
-                         blink::CategorizedWorkerPoolImpl,
+    ::testing::Types<CategorizedWorkerPoolTaskGraphRunnerTestDelegate<
+                         CategorizedWorkerPoolImpl,
                          1>,
-                     blink::CategorizedWorkerPoolTaskGraphRunnerTestDelegate<
-                         blink::CategorizedWorkerPoolImpl,
+                     CategorizedWorkerPoolTaskGraphRunnerTestDelegate<
+                         CategorizedWorkerPoolImpl,
                          2>,
-                     blink::CategorizedWorkerPoolTaskGraphRunnerTestDelegate<
-                         blink::CategorizedWorkerPoolImpl,
+                     CategorizedWorkerPoolTaskGraphRunnerTestDelegate<
+                         CategorizedWorkerPoolImpl,
                          3>,
-                     blink::CategorizedWorkerPoolTaskGraphRunnerTestDelegate<
-                         blink::CategorizedWorkerPoolImpl,
+                     CategorizedWorkerPoolTaskGraphRunnerTestDelegate<
+                         CategorizedWorkerPoolImpl,
                          4>,
-                     blink::CategorizedWorkerPoolTaskGraphRunnerTestDelegate<
-                         blink::CategorizedWorkerPoolImpl,
+                     CategorizedWorkerPoolTaskGraphRunnerTestDelegate<
+                         CategorizedWorkerPoolImpl,
                          5>>;
 
 INSTANTIATE_TYPED_TEST_SUITE_P(
@@ -242,20 +238,20 @@
     TaskGraphRunnerTest,
     CategorizedWorkerPoolImplTaskGraphRunnerTestDelegate_1_5);
 using CategorizedWorkerPoolJobTaskGraphRunnerTestDelegate_1_5 =
-    ::testing::Types<blink::CategorizedWorkerPoolTaskGraphRunnerTestDelegate<
-                         blink::CategorizedWorkerPoolJob,
+    ::testing::Types<CategorizedWorkerPoolTaskGraphRunnerTestDelegate<
+                         CategorizedWorkerPoolJob,
                          1>,
-                     blink::CategorizedWorkerPoolTaskGraphRunnerTestDelegate<
-                         blink::CategorizedWorkerPoolJob,
+                     CategorizedWorkerPoolTaskGraphRunnerTestDelegate<
+                         CategorizedWorkerPoolJob,
                          2>,
-                     blink::CategorizedWorkerPoolTaskGraphRunnerTestDelegate<
-                         blink::CategorizedWorkerPoolJob,
+                     CategorizedWorkerPoolTaskGraphRunnerTestDelegate<
+                         CategorizedWorkerPoolJob,
                          3>,
-                     blink::CategorizedWorkerPoolTaskGraphRunnerTestDelegate<
-                         blink::CategorizedWorkerPoolJob,
+                     CategorizedWorkerPoolTaskGraphRunnerTestDelegate<
+                         CategorizedWorkerPoolJob,
                          4>,
-                     blink::CategorizedWorkerPoolTaskGraphRunnerTestDelegate<
-                         blink::CategorizedWorkerPoolJob,
+                     CategorizedWorkerPoolTaskGraphRunnerTestDelegate<
+                         CategorizedWorkerPoolJob,
                          5>>;
 INSTANTIATE_TYPED_TEST_SUITE_P(
     CategorizedWorkerPoolJob_1_5_Threads,
@@ -264,17 +260,15 @@
 
 // Single threaded tests.
 using CategorizedWorkerPoolImplTaskGraphRunnerTestDelegate =
-    blink::CategorizedWorkerPoolTaskGraphRunnerTestDelegate<
-        blink::CategorizedWorkerPoolImpl,
-        1>;
+    CategorizedWorkerPoolTaskGraphRunnerTestDelegate<CategorizedWorkerPoolImpl,
+                                                     1>;
 INSTANTIATE_TYPED_TEST_SUITE_P(
     CategorizedWorkerPoolImpl,
     SingleThreadTaskGraphRunnerTest,
     CategorizedWorkerPoolImplTaskGraphRunnerTestDelegate);
 using CategorizedWorkerPoolJobTaskGraphRunnerTestDelegate =
-    blink::CategorizedWorkerPoolTaskGraphRunnerTestDelegate<
-        blink::CategorizedWorkerPoolJob,
-        1>;
+    CategorizedWorkerPoolTaskGraphRunnerTestDelegate<CategorizedWorkerPoolJob,
+                                                     1>;
 INSTANTIATE_TYPED_TEST_SUITE_P(
     CategorizedWorkerPoolJob,
     SingleThreadTaskGraphRunnerTest,
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index b0110cee..d7b49d2 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -2352,6 +2352,50 @@
     ]
   }
 
+  # Defines a target that derives from the chrome public application. This
+  # can be either an APK or an app bundle module. This supports
+  # chrome_public_xxx targets (for Android L-M). For Android N+, see instead
+  # monochrome_public_apk_or_module_tmpl() below.
+  #
+  # Variables:
+  #  target_type: Determines the final target type. Should be one of
+  #    'android_apk', or 'android_app_bundle_module'.
+  #  apk_name: For 'android_apk' target types, name of the final APK without
+  #    an .apk suffix (e.g. 'ChromePublic').
+  #  is_base_module: For 'android_app_bundle_module' target types only,
+  #     set to true to indicate that this is a base application module
+  #     (instead of a feature module).
+  template("chrome_public_apk_or_module_tmpl") {
+    _is_bundle_module = invoker.target_type == "android_app_bundle_module"
+    chrome_public_common_apk_or_module_tmpl(target_name) {
+      forward_variables_from(invoker,
+                             [
+                               "add_view_trace_events",
+                               "apk_name",
+                               "bundle_target",
+                               "is_base_module",
+                               "target_type",
+                               "enable_lint",
+                               "enable_multidex",
+                               "lint_baseline_file",
+                               "lint_suppressions_dep",
+                               "lint_suppressions_file",
+                               "manual_jni_registration",
+                             ])
+      deps = chrome_public_shared_deps
+
+      if (_is_bundle_module) {
+        deps += [ ":chrome_bundle_module_pak_assets" ]
+      } else {
+        deps += [ ":chrome_apk_pak_assets" ]
+      }
+
+      shared_libraries = [ ":libchrome" ]
+
+      version_name = chrome_version_name
+    }
+  }
+
   chrome_public_apk_or_module_tmpl("chrome_public_apk") {
     target_type = "android_apk"
     apk_name = "ChromePublic"
@@ -2504,6 +2548,83 @@
     annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
   }
 
+  # Defines a target that derives from the monochrome public application. This
+  # can be either an APK or an app bundle module. Note that these only work
+  # on Android N+ devices, see chrome_public_apk_or_module_tmpl() for a template
+  # that supports generating targets for older Android releases.
+  #
+  # Variables:
+  #   target_type: Either 'android_apk' or 'android_app_bundle_module'.
+  #   apk_name: For APK target types, the final APK name without an .apk
+  #     suffix (e.g. "MonochromePublic").
+  #   is_base_module: For module target types, a boolean indicating whether
+  #     this is a base bundle module (instead of a feature one).
+  #   is_64_bit_browser: When compiling in a 64-bit configuration, a boolean
+  #     indicating whether the browser is 64-bit or 32-bit.
+  #   include_32_bit_webview: When compiling a 64-bit browser configuration, if
+  #     true, a 32-bit WebView library will also be built and included.
+  template("monochrome_public_apk_or_module_tmpl") {
+    _is_trichrome = defined(invoker.is_trichrome) && invoker.is_trichrome
+    _is_bundle = invoker.target_type == "android_app_bundle_module"
+
+    monochrome_public_common_apk_or_module_tmpl(target_name) {
+      forward_variables_from(invoker,
+                             [
+                               "add_view_trace_events",
+                               "apk_name",
+                               "bundle_target",
+                               "expected_android_manifest",
+                               "include_32_bit_webview",
+                               "include_64_bit_webview",
+                               "is_64_bit_browser",
+                               "is_base_module",
+                               "is_trichrome",
+                               "resource_ids_provider_dep",
+                               "static_library_provider",
+                               "target_type",
+                               "use_chromium_linker",
+                             ])
+
+      if (!_is_trichrome) {
+        # Resource allowlist used when generating R.java files and causes
+        # only the webview subset of resources to be marked as non-final.
+        # Strings in this target will also be kept in the base apk rather than placed in the language splits.
+        shared_resources_allowlist_target =
+            "//android_webview:system_webview_no_weblayer_apk"
+
+        # Ensure the localized resources for all locales are used, even when
+        # a smaller set is specified through aapt_locale_allowlist.
+        shared_resources_allowlist_locales = platform_pak_locales
+      }
+
+      deps = []
+      if (_is_bundle) {
+        deps += [
+          "//chrome/android:chrome_base_module_resources",
+
+          # deps in delegate_public_impl_java are put into the Chrome module, but the language deps
+          # are needed by the base module.
+          "//components/language/android:ulp_delegate_public_java",
+        ]
+      } else {
+        deps += [ ":delegate_public_impl_java" ]
+      }
+      if (!_is_trichrome) {
+        deps += [
+          "//android_webview:platform_service_bridge_upstream_implementation_java",
+          "//android_webview/nonembedded:icon_resources",
+          "//android_webview/nonembedded:monochrome_devui_launcher_icon_resources",
+        ]
+        if (!_is_bundle) {
+          deps += [ ":monochrome_java" ]
+        }
+        if (webview_includes_weblayer) {
+          deps += [ "//weblayer/browser/java:upstream_java" ]
+        }
+      }
+    }
+  }
+
   if (android_64bit_target_cpu && skip_secondary_abi_for_cq) {
     group("trichrome_library_apk") {
       deps = [ ":trichrome_library_64_apk" ]
@@ -2512,8 +2633,7 @@
       deps = [ ":monochrome_64_public_apk" ]
     }
   } else {
-    chrome_public_apk_or_module_tmpl("monochrome_public_apk") {
-      is_monochrome = true
+    monochrome_public_apk_or_module_tmpl("monochrome_public_apk") {
       apk_name = "MonochromePublic"
       target_type = "android_apk"
       if (android_64bit_target_cpu) {
@@ -2552,8 +2672,7 @@
   }
 
   if (android_64bit_target_cpu) {
-    chrome_public_apk_or_module_tmpl("monochrome_64_public_apk") {
-      is_monochrome = true
+    monochrome_public_apk_or_module_tmpl("monochrome_64_public_apk") {
       apk_name = "MonochromePublic64"
       target_type = "android_apk"
       is_64_bit_browser = true
@@ -2731,7 +2850,48 @@
         include_32_bit_webview = !skip_secondary_abi_for_cq
       }
 
-      deps = [ ":chrome_test_ar_java" ]
+      # This is where we would add the shared_libraries entry for
+      # :libchromefortest in the non-Monochrome version. However, doing so in the
+      # Monochrome version causes Chrome to crash on startup due to being unable
+      # to load the library, and looking at the libraries included in the APK
+      # shows both libchromefortest and libmonochrome, when only one should be
+      # present. The tests currently work fine with just libmonochrome, so keep
+      # it this way until we actually need the test-only library. This may be
+      # related to monochrome_public_common_apk_or_module_tmpl adding its own
+      # shared libraries, but chrome_public_common_apk_or_module_tmpl not. See
+      # https://crbug.com/974017.
+      deps = [
+        ":chrome_test_ar_java",
+        "//third_party/android_sdk:android_test_mock_java",
+      ]
+
+      # Include ArCore files directly instead of using bundles. This does
+      # require us to explicitly re-declare our dependency on ARCore, which
+      # otherwise should have already been included, since the native libraries
+      # need to know that it is available. Though we'd always need to forcibly
+      # include the manifest DEP here as well
+      deps += [
+        "//third_party/arcore-android-sdk-client:com_google_ar_core_java",
+        "//third_party/arcore-android-sdk-client:com_google_ar_core_java__ignored_manifest",
+      ]
+
+      _libarcore_dir = get_label_info(
+                           "//third_party/arcore-android-sdk-client:com_google_ar_core_java($default_toolchain)",
+                           "target_out_dir") + "/com_google_ar_core_java/jni"
+
+      # We store this as a separate .so in the APK and only load as needed.
+      if (android_64bit_target_cpu) {
+        if (skip_secondary_abi_for_cq) {
+          loadable_modules = [ "$_libarcore_dir/arm64-v8a/libarcore_sdk_c.so" ]
+        } else {
+          secondary_abi_loadable_modules =
+              [ "$_libarcore_dir/armeabi-v7a/libarcore_sdk_c.so" ]
+        }
+      } else {
+        loadable_modules = [ "$_libarcore_dir/armeabi-v7a/libarcore_sdk_c.so" ]
+      }
+
+      additional_apks = [ "//net/android:net_test_support_apk" ]
     }
   }
 
@@ -2954,19 +3114,22 @@
     ]
   }
 
-  template("chrome_bundle_tmpl") {
-    _is_monochrome = defined(invoker.is_monochrome) && invoker.is_monochrome
-    _is_trichrome = defined(invoker.is_trichrome) && invoker.is_trichrome
-    assert(_is_monochrome || _is_trichrome, "TODO: https://crbug.com/1426950")
-
+  template("monochrome_or_trichrome_public_bundle_tmpl") {
     _base_module_target_name = "${invoker.target_name}__base_bundle_module"
-    chrome_public_apk_or_module_tmpl(_base_module_target_name) {
+    _is_trichrome = defined(invoker.is_trichrome) && invoker.is_trichrome
+
+    if (_is_trichrome) {
+      _bundle_name = "TrichromeChrome${invoker.bundle_suffix}"
+    } else {
+      _bundle_name = "MonochromePublic${invoker.bundle_suffix}"
+    }
+
+    monochrome_public_apk_or_module_tmpl(_base_module_target_name) {
       forward_variables_from(invoker,
                              [
                                "add_view_trace_events",
                                "expected_android_manifest",
                                "is_64_bit_browser",
-                               "is_monochrome",
                                "is_trichrome",
                                "include_32_bit_webview",
                                "include_64_bit_webview",
@@ -2974,6 +3137,7 @@
                                "resource_ids_provider_dep",
                              ])
       target_type = "android_app_bundle_module"
+      is_base_module = true
       bundle_target = ":${invoker.target_name}"
 
       if (defined(invoker.expected_android_manifest_template)) {
@@ -2992,7 +3156,6 @@
                                "include_32_bit_webview",
                                "include_64_bit_webview",
                                "is_64_bit_browser",
-                               "is_monochrome",
                                "is_trichrome",
                                "lint_baseline_file",
                                "lint_min_sdk_version",
@@ -3002,19 +3165,20 @@
                                "expected_libs_and_assets",
                                "expected_proguard_config",
                              ])
+      is_monochrome = !_is_trichrome
       base_module_target = ":$_base_module_target_name"
+      bundle_name = _bundle_name
       manifest_package = chrome_public_manifest_package
-      if (_is_trichrome) {
-        bundle_name = "TrichromeChrome${invoker.bundle_suffix}"
-        module_descs = chrome_module_descs
-      } else if (_is_monochrome) {
-        bundle_name = "MonochromePublic${invoker.bundle_suffix}"
+      if (is_monochrome) {
         module_descs = monochrome_module_descs
+      } else {
+        module_descs = chrome_module_descs
       }
       chrome_deps = [ ":delegate_public_impl_java" ]
       if (!_is_trichrome) {
         chrome_deps += [ "//chrome/android:monochrome_java" ]
       }
+
       if (!is_java_debug) {
         proguard_android_sdk_dep = webview_framework_dep
       }
@@ -3043,9 +3207,7 @@
   } else {
     # Public webview targets don't work with non-public sdks.
     # https://crbug.com/1000763
-    chrome_bundle_tmpl("monochrome_public_bundle") {
-      is_monochrome = true
-
+    monochrome_or_trichrome_public_bundle_tmpl("monochrome_public_bundle") {
       # Monochrome bundle is used as our unified lint target, so it needs to set the
       # lowest shipping minSdkVersion to catch all potential NewApi errors.
       lint_min_sdk_version = default_min_sdk_version
@@ -3085,7 +3247,7 @@
       }
     }
 
-    chrome_bundle_tmpl("trichrome_chrome_bundle") {
+    monochrome_or_trichrome_public_bundle_tmpl("trichrome_chrome_bundle") {
       bundle_suffix = ""
       is_trichrome = true
       static_library_provider = ":trichrome_library_apk"
@@ -3198,14 +3360,13 @@
   }
 
   if (android_64bit_target_cpu) {
-    chrome_bundle_tmpl("monochrome_64_public_bundle") {
-      is_monochrome = true
+    monochrome_or_trichrome_public_bundle_tmpl("monochrome_64_public_bundle") {
       bundle_suffix = "64"
       is_64_bit_browser = true
       include_32_bit_webview = false
     }
 
-    chrome_bundle_tmpl("trichrome_chrome_64_bundle") {
+    monochrome_or_trichrome_public_bundle_tmpl("trichrome_chrome_64_bundle") {
       is_trichrome = true
       bundle_suffix = "64"
       is_64_bit_browser = true
@@ -3218,21 +3379,22 @@
     }
 
     if (!skip_secondary_abi_for_cq) {
-      chrome_bundle_tmpl("monochrome_32_public_bundle") {
-        is_monochrome = true
+      monochrome_or_trichrome_public_bundle_tmpl(
+          "monochrome_32_public_bundle") {
         bundle_suffix = "32"
         is_64_bit_browser = false
         include_64_bit_webview = false
       }
 
-      chrome_bundle_tmpl("monochrome_64_32_public_bundle") {
-        is_monochrome = true
+      monochrome_or_trichrome_public_bundle_tmpl(
+          "monochrome_64_32_public_bundle") {
         bundle_suffix = "6432"
         is_64_bit_browser = true
         include_32_bit_webview = true
       }
 
-      chrome_bundle_tmpl("trichrome_chrome_64_32_bundle") {
+      monochrome_or_trichrome_public_bundle_tmpl(
+          "trichrome_chrome_64_32_bundle") {
         is_trichrome = true
         bundle_suffix = "6432"
         is_64_bit_browser = true
@@ -3243,7 +3405,7 @@
               "expectations/$target_name.$target_cpu.libs_and_assets.expected"
         }
       }
-      chrome_bundle_tmpl("trichrome_chrome_32_bundle") {
+      monochrome_or_trichrome_public_bundle_tmpl("trichrome_chrome_32_bundle") {
         is_trichrome = true
         bundle_suffix = "32"
         is_64_bit_browser = false
diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni
index a697eda..5e6f796 100644
--- a/chrome/android/chrome_java_resources.gni
+++ b/chrome/android/chrome_java_resources.gni
@@ -455,6 +455,7 @@
   "java/res/layout/account_divider_preference.xml",
   "java/res/layout/account_management_account_row.xml",
   "java/res/layout/auto_sign_in_first_run_dialog.xml",
+  "java/res/layout/autofill_address_profile_prompt_source_notice.xml",
   "java/res/layout/autofill_billing_address_dropdown.xml",
   "java/res/layout/autofill_card_unmask_prompt.xml",
   "java/res/layout/autofill_card_unmask_prompt_card_details.xml",
@@ -462,10 +463,10 @@
   "java/res/layout/autofill_cc_details.xml",
   "java/res/layout/autofill_expiration_date_fix_flow.xml",
   "java/res/layout/autofill_local_profile_icon.xml",
+  "java/res/layout/autofill_migrate_address_profile_prompt.xml",
   "java/res/layout/autofill_name_fixflow.xml",
   "java/res/layout/autofill_save_address_profile_prompt.xml",
   "java/res/layout/autofill_save_card_base_layout.xml",
-  "java/res/layout/autofill_save_update_address_profile_prompt_footer.xml",
   "java/res/layout/autofill_server_card_editor.xml",
   "java/res/layout/autofill_server_data_edit_link.xml",
   "java/res/layout/autofill_server_data_label.xml",
diff --git a/chrome/android/chrome_public_apk_tmpl.gni b/chrome/android/chrome_public_apk_tmpl.gni
index ef17c6e..28fe242 100644
--- a/chrome/android/chrome_public_apk_tmpl.gni
+++ b/chrome/android/chrome_public_apk_tmpl.gni
@@ -109,6 +109,8 @@
 # Variables:
 #   target_type: Either 'android_apk' or 'android_app_bundle_module'.
 #   apk_name: For APK target types, the final APK name without a suffix.
+#   is_base_module: For bundle module target types, true iff this is a base
+#     application module, instead of a feature module.
 #   shared_libraries: List of native shared libraries targets to include in
 #     the final target (e.g. [ ":libchrome" ]).
 #   is_monochrome: Indicates that this target contains chrome and webview
@@ -122,44 +124,29 @@
 #   Plus all other variables accepted by android_apk() or
 #   android_app_bundle_module(), depending on the target type.
 #
-template("chrome_common_apk_or_module_tmpl") {
-  _target_type = invoker.target_type
-  assert(_target_type == "android_apk" ||
-         _target_type == "android_app_bundle_module" ||
-         _target_type == "instrumentation_test_apk")
+template("chrome_public_common_apk_or_module_tmpl") {
+  assert(
+      invoker.target_type == "android_apk" ||
+          invoker.target_type == "android_app_bundle_module" ||
+          invoker.target_type == "instrumentation_test_apk",
+      "Invalid target_type definition, should be 'android_apk' or 'android_app_bundle_module'")
 
   _is_monochrome = defined(invoker.is_monochrome) && invoker.is_monochrome
   _is_trichrome = defined(invoker.is_trichrome) && invoker.is_trichrome
-  _is_bundle = _target_type == "android_app_bundle_module"
+  _is_bundle = invoker.target_type == "android_app_bundle_module"
 
-  _is_64_bit_browser =
-      android_64bit_target_cpu &&
-      (!defined(invoker.is_64_bit_browser) || invoker.is_64_bit_browser)
   if (_is_trichrome || _is_monochrome) {
     _include_64_bit_webview =
         android_64bit_target_cpu && (!defined(invoker.include_64_bit_webview) ||
                                      invoker.include_64_bit_webview)
     _include_32_bit_webview = !defined(invoker.include_32_bit_webview) ||
                               invoker.include_32_bit_webview
-    _include_primary_abi = !android_64bit_target_cpu || _is_64_bit_browser ||
-                           _include_64_bit_webview
-    _include_secondary_abi = android_64bit_target_cpu &&
-                             (!_is_64_bit_browser || _include_32_bit_webview)
-    if (_include_secondary_abi) {
-      _secondary_out_dir =
-          get_label_info("X($android_secondary_abi_toolchain)", "root_out_dir")
-      not_needed([ "_secondary_out_dir" ])
-    }
-  } else {
-    _include_primary_abi = true
-    _include_secondary_abi = false
-
-    # TODO(agrieve): not_needed needed only when not using crashpad trampoline.
-    not_needed([
-                 "_include_primary_abi",
-                 "_include_secondary_abi",
-               ])
   }
+  _is_64_bit_browser =
+      android_64bit_target_cpu &&
+      (!defined(invoker.is_64_bit_browser) || invoker.is_64_bit_browser)
+  _is_secondary_abi_primary = !_is_64_bit_browser && android_64bit_target_cpu
+  not_needed([ "_is_secondary_abi_primary" ])
 
   assert(!(_is_monochrome && _is_trichrome),
          "Cannot be both trichrome and monochrome!")
@@ -167,6 +154,12 @@
          "If trichrome library is used, static_library_provider must be set " +
              "so that a dep can be added on the library APK.")
 
+  if (!defined(invoker.target_type)) {
+    _target_type = "android_apk"
+  } else {
+    _target_type = invoker.target_type
+  }
+
   if (_is_trichrome) {
     _version_code = TRICHROME_VERSION_MAP["${android_64bit_target_cpu}_${_is_64_bit_browser}_${_include_64_bit_webview}_${_include_32_bit_webview}"]
   } else if (_is_monochrome) {
@@ -176,150 +169,104 @@
     _version_code = chrome_modern_version_code
   }
 
-  if (defined(invoker.manifest_package)) {
-    _manifest_package = invoker.manifest_package
-  } else {
-    _manifest_package = chrome_public_manifest_package
-  }
-
-  _android_manifest = "$target_gen_dir/$target_name/AndroidManifest.xml"
-
-  # TODO(crbug.com/1411557): Move out of manifest/ when downstream is updated.
-  # _split.xml is used in chrome_bundle template.
-  _split_android_manifest =
-      "$target_gen_dir/manifest/$target_name/AndroidManifest_split.xml"
-  _android_manifest_target_name = "${target_name}__android_manifest"
-  split_manifest_template(_android_manifest_target_name) {
-    definitions_in_split = _is_bundle
-    split_input = "//chrome/android/java/AndroidManifest_split.xml"
-    split_output = _split_android_manifest
-    includes = []
-    output = _android_manifest
-    variables = default_chrome_public_jinja_variables +
-                [ "manifest_package=$_manifest_package" ]
-    if (_is_trichrome) {
-      input = "//chrome/android/java/AndroidManifest_trichrome_chrome.xml"
-      includes = [ "//chrome/android/java/AndroidManifest.xml" ]
-      variables +=
-          trichrome_jinja_variables + [ "trichrome_version=$_version_code" ]
-    } else if (_is_monochrome) {
-      input = "//chrome/android/java/AndroidManifest_monochrome.xml"
-      includes = [
-        "//android_webview/nonembedded/java/AndroidManifest.xml",
-        "//chrome/android/java/AndroidManifest.xml",
-      ]
-      variables += monochrome_android_manifest_jinja_variables
-      if (_is_64_bit_browser) {
-        variables += [ "webview_library=libmonochrome_64.so" ]
-      } else {
-        variables += [ "webview_library=libmonochrome.so" ]
-      }
+  # TODO(crbug.com/1411557): Remove option for custom manifest.
+  if (!defined(invoker.android_manifest)) {
+    if (defined(invoker.manifest_package)) {
+      _manifest_package = invoker.manifest_package
     } else {
-      input = "//chrome/android/java/AndroidManifest.xml"
+      _manifest_package = chrome_public_manifest_package
     }
-    if (_is_monochrome || _is_trichrome) {
-      _force_32_bit = _include_32_bit_webview && _include_64_bit_webview &&
-                      !_is_64_bit_browser
-      variables += [
-        "force_32_bit=$_force_32_bit",
-        "include_arcore_manifest_flag=$enable_arcore",
-      ]
 
-      # TODO(crbug.com/1411557): Remove block.
-      if (_is_64_bit_browser) {
-        variables -= [ use_32bit_abi_jinja_variable ]
+    _android_manifest = "$target_gen_dir/$target_name/AndroidManifest.xml"
+
+    # TODO(crbug.com/1411557): Move out of manifest/ when downstream is updated.
+    # _split.xml is used in chrome_bundle template.
+    _split_android_manifest =
+        "$target_gen_dir/manifest/$target_name/AndroidManifest_split.xml"
+    _android_manifest_target_name = "${target_name}__android_manifest"
+    split_manifest_template(_android_manifest_target_name) {
+      definitions_in_split = _is_bundle
+      split_input = "//chrome/android/java/AndroidManifest_split.xml"
+      split_output = _split_android_manifest
+      includes = []
+      output = _android_manifest
+      variables = default_chrome_public_jinja_variables +
+                  [ "manifest_package=$_manifest_package" ]
+      if (_is_trichrome) {
+        input = "//chrome/android/java/AndroidManifest_trichrome_chrome.xml"
+        includes = [ "//chrome/android/java/AndroidManifest.xml" ]
+        variables +=
+            trichrome_jinja_variables + [ "trichrome_version=$_version_code" ]
+      } else if (_is_monochrome) {
+        input = "//chrome/android/java/AndroidManifest_monochrome.xml"
+        includes = [
+          "//android_webview/nonembedded/java/AndroidManifest.xml",
+          "//chrome/android/java/AndroidManifest.xml",
+        ]
+        variables += monochrome_android_manifest_jinja_variables
+        if (_is_64_bit_browser) {
+          variables += [ "webview_library=libmonochrome_64.so" ]
+        } else {
+          variables += [ "webview_library=libmonochrome.so" ]
+        }
+      } else {
+        input = "//chrome/android/java/AndroidManifest.xml"
       }
-    }
-    if (defined(invoker.jinja_input)) {
-      includes += [ input ]
-      input = invoker.jinja_input
-    }
-    if (defined(invoker.jinja_extra_variables)) {
-      variables += invoker.jinja_extra_variables
-    }
-    if (defined(invoker.jinja_extra_includes)) {
-      includes += invoker.jinja_extra_includes
+      if (_is_monochrome || _is_trichrome) {
+        _force_32_bit = _include_32_bit_webview && _include_64_bit_webview &&
+                        !_is_64_bit_browser
+        variables += [
+          "force_32_bit=$_force_32_bit",
+          "include_arcore_manifest_flag=$enable_arcore",
+        ]
+
+        # TODO(crbug.com/1411557): Remove block.
+        if (_is_64_bit_browser) {
+          variables -= [ use_32bit_abi_jinja_variable ]
+        }
+      }
+      if (defined(invoker.jinja_input)) {
+        includes += [ input ]
+        input = invoker.jinja_input
+      }
+      if (defined(invoker.jinja_extra_variables)) {
+        variables += invoker.jinja_extra_variables
+      }
+      if (defined(invoker.jinja_extra_includes)) {
+        includes += invoker.jinja_extra_includes
+      }
     }
   }
   target(_target_type, target_name) {
-    android_manifest = _android_manifest
-    android_manifest_dep = ":$_android_manifest_target_name"
-    manifest_package = _manifest_package
+    forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
+    forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
 
-    if (defined(invoker.min_sdk_version)) {
-      min_sdk_version = invoker.min_sdk_version
-    } else if (_is_trichrome) {
+    if (!defined(assert_no_deps)) {
+      assert_no_deps = []
+    }
+
+    # https://crbug.com/1415351
+    assert_no_deps += [
+      "//third_party/androidx:androidx_window_extensions_core_core_java",
+      "//third_party/androidx:androidx_window_sidecar_sidecar_java",
+      "//third_party/androidx:androidx_window_window_java_java",
+    ]
+
+    # TODO(crbug.com/1411557): Do not allows custom manifest dep.
+    if (defined(_android_manifest_target_name)) {
+      android_manifest = _android_manifest
+      android_manifest_dep = ":$_android_manifest_target_name"
+      manifest_package = _manifest_package
+    }
+
+    if (!defined(min_sdk_version) && _is_trichrome) {
       min_sdk_version = 29
     }
-    if (defined(invoker.version_name)) {
-      version_name = invoker.version_name
-    } else {
-      version_name = chrome_version_name
-    }
-    if (defined(invoker.version_code)) {
-      # Override for the actual versionCode, but not for trichrome_version.
-      version_code = invoker.version_code
-    } else {
-      version_code = _version_code
-    }
-    if (defined(invoker.expected_android_manifest)) {
+    if (defined(expected_android_manifest)) {
       expected_android_manifest_version_code_offset = chrome_version_code
       expected_android_manifest_library_version_offset = chrome_version_code
     }
 
-    if (_target_type == "android_apk") {
-      command_line_flags_file = "chrome-command-line"
-    }
-
-    if (_is_bundle) {
-      is_base_module = true
-
-      # Sets ISOLATED_SPLITS_ENABLED in BuildConfig.java.
-      isolated_splits_enabled = true
-    }
-
-    if (_is_monochrome) {
-      alternative_android_sdk_dep = webview_framework_dep
-      app_as_shared_lib = true
-
-      # Resource allowlist used when generating R.java files and causes
-      # only the webview subset of resources to be marked as non-final.
-      # Strings in this target will also be kept in the base apk rather than placed in the language splits.
-      shared_resources_allowlist_target =
-          "//android_webview:system_webview_no_weblayer_apk"
-
-      # Ensure the localized resources for all locales are used, even when
-      # a smaller set is specified through aapt_locale_allowlist.
-      shared_resources_allowlist_locales = platform_pak_locales
-
-      product_config_java_packages = [
-        "org.chromium.chrome.browser",
-        webview_product_config_java_package,
-      ]
-
-      if (webview_includes_weblayer) {
-        product_config_java_packages += [ weblayer_product_config_java_package ]
-      }
-    } else {
-      product_config_java_packages = [ "org.chromium.chrome.browser" ]
-    }
-
-    if (enable_silent_java_assert_reporting) {
-      custom_assertion_handler = crash_reporting_assertion_handler
-    }
-
-    if (allow_jni_multiplexing) {
-      enable_jni_multiplexing = true
-    }
-
-    # TODO(agrieve): Make this the default for apks with minSdkVersion > 21.
-    if (_is_monochrome || _is_trichrome) {
-      no_xml_namespaces = true
-    }
-
-    # Include resource strings files only for supported locales.
-    aapt_locale_allowlist = platform_pak_locales
-
     resource_exclusion_regex = common_resource_exclusion_regex
     resource_exclusion_exceptions = common_resource_exclusion_exceptions
 
@@ -329,7 +276,7 @@
       "*ic_lock.*",  # Bottom edge seems misaligned.
     ]
 
-    # Most of these, with the exception of resource_exclusion_exceptions,
+    # Note most of these, with the exception of resource_exclusion_exceptions,
     # are currently duplicated in system_webview_apk_tmpl.gni.
 
     # Used only by alert dialog on tiny screens.
@@ -343,236 +290,256 @@
     # Instead of manually filtering, unused resource removal would be better:
     # https://crbug.com/636448
     resource_exclusion_regex += "|${_material_package}/xml.*badge_"
+    _material_package = "*com_google_android_material*"
 
-    if (!is_java_debug) {
-      # Android supports webp transparent resources properly since API level 18,
-      # so this can only be activated for modern ones (which target API >= 21).
-      png_to_webp = true
+    if (!_is_monochrome) {
+      product_config_java_packages = [ "org.chromium.chrome.browser" ]
+    }
 
-      proguard_enabled = true
-      proguard_configs = [ "//chrome/android/proguard/main.flags" ]
-      if (_is_monochrome) {
-        proguard_configs +=
-            [ "//android_webview/nonembedded/java/proguard.flags" ]
-      }
-      if (defined(invoker.proguard_configs)) {
-        proguard_configs += invoker.proguard_configs
-      }
+    # Android supports webp transparent resources properly since API level 18,
+    # so this can only be activated for modern ones (which target API >= 21).
+    if (!defined(png_to_webp)) {
+      png_to_webp = !is_java_debug
+    }
 
-      # We only optimize resources for bundles since APKs are not shipped.
-      # Resources only live in the base module atm as such we only need to set
-      # these on the base module
-      if (_is_bundle) {
-        # Removes metadata needed for Resources.getIdentifier("resource_name").
-        strip_resource_names = true
+    # We only optimize resources for bundles since APKs are not shipped.
+    # Resources only live in the base module atm as such we only need to set
+    # these on the base module
+    if (_is_bundle) {
+      # Removes metadata needed for Resources.getIdentifier("resource_name").
+      strip_resource_names = !is_java_debug
 
-        # Shortens resource file names in apk eg: res/drawable/button.xml -> res/a.xml
-        short_resource_paths = true
+      # Shortens resource file names in apk eg: res/drawable/button.xml -> res/a.xml
+      short_resource_paths = !is_java_debug
 
-        # Removes unused resources from the apk. Only enabled on official builds
-        # since it adds a slow step and serializes the build graph causing fewer
-        # expensive tasks (eg: proguarding, resource optimization) to be run in
-        # parallel by adding dependencies between them (adds around 10-20
-        # seconds on my machine).
-        strip_unused_resources = is_official_build
+      # Removes unused resources from the apk. Only enabled on official builds
+      # since it adds a slow step and serializes the build graph causing fewer
+      # expensive tasks (eg: proguarding, resource optimization) to be run in
+      # parallel by adding dependencies between them (adds around 10-20
+      # seconds on my machine).
+      strip_unused_resources = is_official_build
+    }
 
-        # Resources config for blocklisting resource names from obfuscation
-        resources_config_paths = [ "//chrome/android/aapt2.config" ]
-        if (_is_monochrome || _is_trichrome) {
-          resources_config_paths += [ "//android_webview/aapt2.config" ]
-        }
-        if (defined(invoker.resources_config_paths)) {
-          resources_config_paths += invoker.resources_config_paths
+    if (!defined(aapt_locale_allowlist)) {
+      # Include resource strings files only for supported locales.
+      aapt_locale_allowlist = platform_pak_locales
+    }
+
+    if (!defined(use_chromium_linker)) {
+      # The Chromium Linker depends on ASharedMemory_create() introduced in O.
+      use_chromium_linker = chromium_linker_supported && _is_trichrome
+    }
+
+    if (_is_trichrome) {
+      static_library_provider_use_secondary_abi = _is_secondary_abi_primary
+
+      # http://crbug.com/1042107.
+      if (is_component_build) {
+        if (android_64bit_target_cpu && _is_64_bit_browser) {
+          main_component_library = "libmonochrome_64.cr.so"
+        } else {
+          main_component_library = "libmonochrome.cr.so"
         }
       }
     }
 
-    deps = [
-      "//chrome/android:chrome_base_module_resources",
-      "//chrome/android:chrome_public_non_pak_assets",
-    ]
-
-    # TODO(agrieve): Make uncondtional when moving to trampoline.
-    if (_is_monochrome || _is_trichrome) {
-      deps += [ "//components/crash/android:handler_java" ]
-    }
-    if (_is_monochrome) {
-      deps += [ "//chrome/android:base_monochrome_module_java" ]
-    } else {
-      deps += [ "//chrome/android:base_module_java" ]
-    }
-    if (defined(invoker.deps)) {
-      deps += invoker.deps
-    }
-
-    if (!_is_trichrome) {
-      # These go in trichrome library.
+    if (!_is_monochrome && !_is_trichrome) {
       deps += [
+        "//components/crash/core/app:chrome_crashpad_handler_named_as_so",
         "//gin:v8_snapshot_assets",
         "//third_party/icu:icu_assets",
       ]
+      if (!defined(loadable_modules)) {
+        loadable_modules = []
+      }
+      loadable_modules += [ "$root_out_dir/libchrome_crashpad_handler.so" ]
+      if (!defined(library_always_compress)) {
+        library_always_compress = []
+      }
+      library_always_compress += [
+        "libchrome_crashpad_handler.so",
+        "libchromium_android_linker.so",
+      ]
+    }
 
-      # TODO(agrieve): This is excluded from trichrome in preparation for
-      # "synchronized proguarding", which we've since abandoned. Enable for
-      # trichrome, or just remove the version check altogether.
+    if (dfmify_dev_ui && !_is_bundle) {
+      # Dev UI is a feature in a DFM, and APKs don't use DFMs. To make the code
+      # available for APKs add a dependency on it.
+      deps += [ "//chrome/android/features/dev_ui:java" ]
+    }
+    if (enable_vr && !_is_bundle) {
+      # VR is a feature in a DFM, and APKs don't use DFMs, but we
+      # unconditionally include vr code in our native library. To make the code
+      # available for APKs, add a dependency on it.
+      deps += [ "//chrome/android/features/vr:java" ]
+    }
+
+    if (!is_java_debug) {
+      proguard_enabled = true
+      if (!defined(proguard_configs)) {
+        proguard_configs = []
+      }
+      proguard_configs += [ "//chrome/android/proguard/main.flags" ]
+    }
+
+    if (use_chromium_linker) {
+      if (_is_secondary_abi_primary) {
+        _secondary_linker = "//base/android/linker:chromium_android_linker($android_secondary_abi_toolchain)"
+        deps += [ _secondary_linker ]
+        _secondary_out_dir = get_label_info(_secondary_linker, "root_out_dir")
+        secondary_abi_loadable_modules +=
+            [ "$_secondary_out_dir/libchromium_android_linker$shlib_extension" ]
+      } else {
+        deps += [ "//base/android/linker:chromium_android_linker" ]
+        loadable_modules +=
+            [ "$root_out_dir/libchromium_android_linker$shlib_extension" ]
+      }
+    }
+    if (build_with_internal_optimization_guide) {
+      if (_is_secondary_abi_primary) {
+        _secondary_optimization_guide = "//components/optimization_guide/internal:optimization_guide_internal($android_secondary_abi_toolchain)"
+        deps += [ _secondary_optimization_guide ]
+        _secondary_out_dir =
+            get_label_info(_secondary_optimization_guide, "root_out_dir")
+        secondary_abi_loadable_modules +=
+            [ "$_secondary_out_dir/liboptimization_guide_internal.so" ]
+      } else {
+        deps += [ "//components/optimization_guide/internal:optimization_guide_internal" ]
+        loadable_modules +=
+            [ "$root_out_dir/liboptimization_guide_internal.so" ]
+      }
+    }
+    if (_target_type == "android_apk") {
+      command_line_flags_file = "chrome-command-line"
+    }
+    if (!_is_trichrome) {
       build_config_include_product_version_resource = true
       deps += [ "//chrome/android:product_version_resources" ]
     }
 
+    if (!_is_bundle || !(_is_monochrome || _is_trichrome)) {
+      deps += [ "//chrome/android:chrome_all_java" ]
+    }
+
     if (_is_bundle) {
       # Required to support macro resources.
       # See https://crbug.com/1278419
       deps += [ ":${target_name}__all_dfm_resources" ]
-    } else {
-      # For bundles, this exists in the "chrome" split.
-      deps += [ "//chrome/android:chrome_all_java" ]
-
-      if (dfmify_dev_ui) {
-        # For bundles, Dev UI is a feature in a DFM.
-        deps += [ "//chrome/android/features/dev_ui:java" ]
-      }
-      if (enable_vr) {
-        # For bundles, VR is a feature in a DFM.
-        deps += [ "//chrome/android/features/vr:java" ]
-      }
-    }
-
-    if (_is_monochrome) {
-      deps += [
-        "//android_webview/glue:glue_java",
-        "//android_webview/nonembedded:monochrome_devui_launcher_icon_resources",
-        "//android_webview/nonembedded:nonembedded_java",
-      ]
-
-      # For bundles, this lives in chrome split.
-      if (!_is_bundle) {
-        deps += [ "//chrome/android:monochrome_java" ]
-      }
-
-      if (_include_primary_abi) {
-        deps += [ "//android_webview:monochrome_webview_primary_abi_assets" ]
-      }
-      if (_include_secondary_abi) {
-        deps += [ "//android_webview:monochrome_webview_secondary_abi_assets" ]
-      }
-    }
-
-    if (_is_bundle && _is_monochrome) {
-      deps += [ "//chrome/android:monochrome_bundle_module_pak_assets" ]
-    } else if (_is_bundle && _is_trichrome) {
-      deps += [ "//chrome/android:trichrome_chrome_bundle_module_pak_assets" ]
-    } else if (_is_bundle) {
-      deps += [ "//chrome/android:chrome_bundle_module_pak_assets" ]
-    } else if (_is_monochrome) {
-      deps += [ "//chrome/android:monochrome_apk_pak_assets" ]
-    } else {
-      assert(!_is_trichrome)
-      deps += [ "//chrome/android:chrome_apk_pak_assets" ]
-    }
-
-    # https://crbug.com/1415351
-    assert_no_deps = [
-      "//third_party/androidx:androidx_window_extensions_core_core_java",
-      "//third_party/androidx:androidx_window_sidecar_sidecar_java",
-      "//third_party/androidx:androidx_window_window_java_java",
-    ]
-    if (defined(invoker.assert_no_deps)) {
-      assert_no_deps += invoker.assert_no_deps
     }
 
     # Unwind tables are included in the stack_unwinder DFM on Android, so they
     # aren't needed for bundle builds. However, we keep them for non-bundle
     # builds, such as test and development apks (e.g. chrome_public_apk), to
     # allow tests and developers to use them directly.
-    if (!defined(invoker.shared_libraries) && !_is_bundle &&
-        add_unwind_tables_in_chrome_32bit_apk &&
-        (target_cpu == "arm" ||
-         (target_cpu == "arm64" && !_is_64_bit_browser))) {
-      if (_is_monochrome || _is_trichrome) {
-        deps += [ "//chrome/android:libmonochrome_unwind_table_assets" ]
-      } else {
-        deps += [ "//chrome/android:libchrome_unwind_table_assets" ]
-      }
-    }
+    if (!_is_bundle && add_unwind_tables_in_chrome_32bit_apk) {
+      _needs_32bit_lib =
+          target_cpu == "arm" || ((_is_monochrome || _is_trichrome) &&
+                                  target_cpu == "arm64" && !_is_64_bit_browser)
 
-    data_deps = []
-    if (defined(invoker.data_deps)) {
-      data_deps += invoker.data_deps
+      if (_needs_32bit_lib) {
+        if (_is_monochrome || _is_trichrome) {
+          deps += [ "//chrome/android:libmonochrome_unwind_table_assets" ]
+        } else {
+          deps += [ "//chrome/android:libchrome_unwind_table_assets" ]
+        }
+      }
     }
 
     # Prefer to add this data_dep on the final target instead of java targets
     # like chrome_all_java so that all other targets can build in parallel with
     # lint.
     if (!disable_android_lint) {
+      if (!defined(data_deps)) {
+        data_deps = []
+      }
       data_deps += [ "//chrome/android:android_lint" ]
     }
 
-    shared_libraries = []
-    loadable_modules = []
-    if (android_64bit_target_cpu) {
-      secondary_abi_shared_libraries = []
-      secondary_abi_loadable_modules = []
-    }
-    if (defined(invoker.loadable_modules)) {
-      loadable_modules = invoker.loadable_modules
-    }
-    if (defined(invoker.secondary_abi_loadable_modules)) {
-      secondary_abi_loadable_modules = invoker.secondary_abi_loadable_modules
+    if (enable_silent_java_assert_reporting) {
+      custom_assertion_handler = crash_reporting_assertion_handler
     }
 
-    if (_is_64_bit_browser && build_hwasan_splits) {
-      _hwasan_toolchain = "//build/toolchain/android:android_clang_arm64_hwasan"
+    if (allow_jni_multiplexing) {
+      enable_jni_multiplexing = true
     }
 
-    if (defined(invoker.shared_libraries)) {
-      shared_libraries += invoker.shared_libraries
-    } else if (_is_monochrome) {
-      if (android_64bit_target_cpu) {
-        # Build //android_webview:monochrome with the opposite bitness that
-        # Chrome runs in.
-        if (_is_64_bit_browser) {
-          shared_libraries += [ "//chrome/android:libmonochrome_64" ]
-          if (_include_32_bit_webview) {
-            secondary_abi_shared_libraries += [ "//android_webview:monochrome_64($android_secondary_abi_toolchain)" ]
-          }
-          if (build_hwasan_splits) {
-            shared_libraries +=
-                [ "//chrome/android:libmonochrome_64($_hwasan_toolchain)" ]
-          }
-        } else {
-          if (_include_64_bit_webview) {
-            shared_libraries += [ "//android_webview:monochrome" ]
-          }
-          secondary_abi_shared_libraries += [
-            "//chrome/android:libmonochrome($android_secondary_abi_toolchain)",
-          ]
-        }
-      } else {
-        shared_libraries += [ "//chrome/android:libmonochrome" ]
+    if (!defined(version_name)) {
+      version_name = chrome_version_name
+    }
+    version_code = _version_code
+
+    # Override for the actual versionCode, but not for trichrome_version.
+    if (defined(invoker.version_code)) {
+      version_code = invoker.version_code
+    }
+  }
+}
+
+# The equivalent of chrome_common_apk_or_module_tmpl for all builds of
+# monochrome and trichrome chrome.
+template("monochrome_public_common_apk_or_module_tmpl") {
+  chrome_public_common_apk_or_module_tmpl(target_name) {
+    _overrides = {
+      _is_bundle_module = defined(invoker.target_type) &&
+                          invoker.target_type == "android_app_bundle_module"
+
+      if (_is_bundle_module) {
+        assert(
+            defined(invoker.is_base_module),
+            "_is_bundle_module is true but the invoker does not define is_base_module!")
       }
-    } else if (!_is_trichrome) {
-      shared_libraries += [ "//chrome/android:libchrome" ]
-    }
 
-    # TODO(agrieve): Enable for chrome_public_apk as well.
-    if (enable_arcore && (_is_monochrome || _is_trichrome)) {
-      # The arcore manifest needs to be merged into the base module because
-      # the Play Store verifies the com.google.ar.core.min_apk_version
-      # meta-data tag is in the base manifest.
-      deps += [
-        "//third_party/arcore-android-sdk-client:com_google_ar_core_java",
-        "//third_party/arcore-android-sdk-client:com_google_ar_core_java__ignored_manifest",
+      is_trichrome = defined(invoker.is_trichrome) && invoker.is_trichrome
+      is_monochrome = !is_trichrome
+
+      shared_libraries = []
+      if (defined(invoker.shared_libraries)) {
+        shared_libraries += invoker.shared_libraries
+      }
+      secondary_abi_shared_libraries = []
+      if (defined(invoker.secondary_abi_shared_libraries)) {
+        secondary_abi_shared_libraries += invoker.secondary_abi_shared_libraries
+      }
+      loadable_modules = []
+      if (defined(invoker.loadable_modules)) {
+        loadable_modules = invoker.loadable_modules
+      }
+      secondary_abi_loadable_modules = []
+      if (defined(invoker.secondary_abi_loadable_modules)) {
+        secondary_abi_loadable_modules = invoker.secondary_abi_loadable_modules
+      }
+      native_lib_placeholders = []
+      if (defined(invoker.native_lib_placeholders)) {
+        native_lib_placeholders = invoker.native_lib_placeholders
+      }
+      secondary_native_lib_placeholders = []
+      if (defined(invoker.secondary_native_lib_placeholders)) {
+        secondary_native_lib_placeholders =
+            invoker.secondary_native_lib_placeholders
+      }
+
+      deps = [
+        "//chrome/android:chrome_public_non_pak_assets",
+        "//components/crash/android:handler_java",
       ]
+      if (defined(invoker.deps)) {
+        deps += invoker.deps
+      }
 
-      # For Trichrome, the native library is added to TrichromeLibrary.apk so
-      # it's not needed here.
-      if (!_is_trichrome) {
-        _arcore_target = "//third_party/arcore-android-sdk-client:com_google_ar_core_J__unpack_aar"
-        _libarcore_dir = get_label_info(_arcore_target, "target_out_dir") +
-                         "/com_google_ar_core_java/jni"
+      if (_is_bundle_module && invoker.is_base_module && enable_arcore &&
+          is_monochrome) {
+        # AR DFM is disabled - set the loadable_modules /
+        # secondary_abi_loadable_modules to what would be brought in by the
+        # module. The AR Java will be brought in by the chrome_bundle target.
+        # This needs to happen for monochrome builds of base module if ARCore is
+        # enabled. For Trichrome, the native library is added to
+        # TrichromeLibrary.apk so it's not needed here.
+        _libarcore_dir = get_label_info(
+                             "//third_party/arcore-android-sdk-client:com_google_ar_core_java($default_toolchain)",
+                             "target_out_dir") + "/com_google_ar_core_java/jni"
 
         if (android_64bit_target_cpu) {
-          if (_is_64_bit_browser) {
+          if (invoker.is_64_bit_browser) {
             loadable_modules +=
                 [ "$_libarcore_dir/arm64-v8a/libarcore_sdk_c.so" ]
           } else {
@@ -584,164 +551,234 @@
               [ "$_libarcore_dir/armeabi-v7a/libarcore_sdk_c.so" ]
         }
       }
-    }
-    library_always_compress = []
-    if (defined(invoker.library_always_compress)) {
-      library_always_compress = invoker.library_always_compress
-    }
 
-    # TODO(agrieve): Use Crashpad trampoline in chrome_public_apk.
-    if (!_is_monochrome && !_is_trichrome) {
-      deps +=
-          [ "//components/crash/core/app:chrome_crashpad_handler_named_as_so" ]
-      loadable_modules += [ "$root_out_dir/libchrome_crashpad_handler.so" ]
-      library_always_compress += [ "libchrome_crashpad_handler.so" ]
-    } else if (!_is_trichrome) {
-      # Crashpad trampoline lives in TrichromeLibrary.apk.
-      # https://chromium.googlesource.com/chromium/src/+/main/docs/android_native_libraries.md#Crashpad-Packaging
-      if (_include_primary_abi) {
-        deps += [
-          "//third_party/crashpad/crashpad/handler:crashpad_handler_trampoline",
-        ]
-        loadable_modules +=
-            [ "$root_out_dir/libcrashpad_handler_trampoline.so" ]
-      }
-      if (_include_secondary_abi) {
-        deps += [ "//third_party/crashpad/crashpad/handler:crashpad_handler_trampoline($android_secondary_abi_toolchain)" ]
-        secondary_abi_loadable_modules +=
-            [ "$_secondary_out_dir/libcrashpad_handler_trampoline.so" ]
-      }
-    }
-
-    # The Chromium Linker depends on ASharedMemory_create() introduced in O.
-    use_chromium_linker = chromium_linker_supported && _is_trichrome
-
-    if (use_chromium_linker) {
-      if (android_64bit_target_cpu && !_is_64_bit_browser) {
-        deps += [ "//base/android/linker:chromium_android_linker($android_secondary_abi_toolchain)" ]
-        secondary_abi_loadable_modules +=
-            [ "$_secondary_out_dir/libchromium_android_linker$shlib_extension" ]
-      } else {
-        deps += [ "//base/android/linker:chromium_android_linker" ]
-        loadable_modules +=
-            [ "$root_out_dir/libchromium_android_linker$shlib_extension" ]
-      }
-      if (_is_64_bit_browser && build_hwasan_splits) {
-        deps += [
-          "//base/android/linker:chromium_android_linker($_hwasan_toolchain)",
-        ]
-        _hwasan_outdir = get_label_info(":($_hwasan_toolchain)", "root_out_dir")
-        loadable_modules +=
-            [ "$_hwasan_outdir/libchromium_android_linker$shlib_extension" ]
-      }
-    }
-
-    if (build_with_internal_optimization_guide) {
-      if (android_64bit_target_cpu && !_is_64_bit_browser) {
-        _secondary_optimization_guide = "//components/optimization_guide/internal:optimization_guide_internal($android_secondary_abi_toolchain)"
-        deps += [ _secondary_optimization_guide ]
-        secondary_abi_loadable_modules +=
-            [ "$_secondary_out_dir/liboptimization_guide_internal.so" ]
-      } else {
-        deps += [ "//components/optimization_guide/internal:optimization_guide_internal" ]
-        loadable_modules +=
-            [ "$root_out_dir/liboptimization_guide_internal.so" ]
-      }
-    }
-
-    if (_is_trichrome) {
-      if (android_64bit_target_cpu && !_is_64_bit_browser) {
-        static_library_provider_use_secondary_abi = true
+      if (_is_bundle_module) {
+        # Sets ISOLATED_SPLITS_ENABLED in BuildConfig.java.
+        isolated_splits_enabled = true
       }
 
-      # Include placeholder libraries to make Chrome multiarch in the same way
-      # as Monochrome, even though Chrome only runs with one of the two
-      # bitnesses. This allows the "32-bit" and "64-bit" versions of Chrome to
-      # depend on their respective versions of the shared library APK even
-      # though they're functionally the same.
-      if (_include_primary_abi && loadable_modules == []) {
-        native_lib_placeholders = [ "libdummy.so" ]
-      }
-      if (_include_secondary_abi && secondary_abi_loadable_modules == []) {
-        secondary_native_lib_placeholders = [ "libdummy.so" ]
-      }
+      if (_is_bundle_module && invoker.is_base_module) {
+        # The arcore manifest needs to be merged into the base module because
+        # the Play Store verifies the com.google.ar.core.min_apk_version
+        # meta-data tag is in the base manifest.
+        if (enable_arcore) {
+          deps += [
+            "//third_party/arcore-android-sdk-client:com_google_ar_core_java",
+            "//third_party/arcore-android-sdk-client:com_google_ar_core_java__ignored_manifest",
+          ]
+        }
 
-      # http://crbug.com/1042107.
-      if (is_component_build) {
-        if (_is_64_bit_browser) {
-          main_component_library = "libmonochrome_64.cr.so"
+        if (is_monochrome) {
+          deps += [ "//chrome/android:base_monochrome_module_java" ]
         } else {
-          main_component_library = "libmonochrome.cr.so"
+          deps += [ "//chrome/android:base_module_java" ]
+        }
+      }
+
+      if (android_64bit_target_cpu && (is_monochrome || is_trichrome)) {
+        _include_64_bit_webview = !defined(invoker.include_64_bit_webview) ||
+                                  invoker.include_64_bit_webview
+        _include_32_bit_webview = !defined(invoker.include_32_bit_webview) ||
+                                  invoker.include_32_bit_webview
+      }
+      if (is_monochrome) {
+        product_config_java_packages = [
+          "org.chromium.chrome.browser",
+          webview_product_config_java_package,
+        ]
+
+        if (webview_includes_weblayer) {
+          product_config_java_packages +=
+              [ weblayer_product_config_java_package ]
+        }
+
+        # Flag whether additional deps and libs should be included for each ABI.
+        _include_primary_support = false
+        _include_secondary_support = false
+
+        if (android_64bit_target_cpu) {
+          # Build //android_webview:monochrome with the opposite bitness that
+          # Chrome runs in.
+          if (invoker.is_64_bit_browser) {
+            _include_primary_support = true
+            shared_libraries += [ "//chrome/android:libmonochrome_64" ]
+            if (_include_32_bit_webview) {
+              secondary_abi_shared_libraries += [ "//android_webview:monochrome_64($android_secondary_abi_toolchain)" ]
+              _include_secondary_support = true
+            }
+          } else {
+            secondary_abi_shared_libraries +=
+                [ "//chrome/android:monochrome_secondary_abi_lib" ]
+            _include_secondary_support = true
+            if (_include_64_bit_webview) {
+              shared_libraries += [ "//android_webview:monochrome" ]
+              _include_primary_support = true
+            }
+          }
+        } else {
+          shared_libraries += [ "//chrome/android:libmonochrome" ]
+          _include_primary_support = true
+        }
+
+        deps += [
+          "//android_webview/glue:glue_java",
+          "//android_webview/nonembedded:nonembedded_java",
+        ]
+        if (!_is_bundle_module) {
+          deps += [ "//chrome/android:monochrome_java" ]
+        }
+
+        if (_include_primary_support) {
+          deps += [
+            "//android_webview:monochrome_webview_primary_abi_assets",
+            "//third_party/crashpad/crashpad/handler:crashpad_handler_trampoline",
+          ]
+          loadable_modules +=
+              [ "$root_out_dir/libcrashpad_handler_trampoline.so" ]
+        }
+        if (_include_secondary_support) {
+          _trampoline =
+              "//third_party/crashpad/crashpad/handler:" +
+              "crashpad_handler_trampoline($android_secondary_abi_toolchain)"
+
+          deps += [
+            "//android_webview:monochrome_webview_secondary_abi_assets",
+            _trampoline,
+          ]
+
+          _secondary_out_dir = get_label_info(_trampoline, "root_out_dir")
+          secondary_abi_loadable_modules +=
+              [ "$_secondary_out_dir/libcrashpad_handler_trampoline.so" ]
+        }
+
+        if (defined(invoker.alternative_android_sdk_dep)) {
+          alternative_android_sdk_dep = invoker.alternative_android_sdk_dep
+        } else {
+          alternative_android_sdk_dep = webview_framework_dep
+        }
+        if (defined(invoker.app_as_shared_lib)) {
+          app_as_shared_lib = invoker.app_as_shared_lib
+        } else {
+          app_as_shared_lib = true
+        }
+        _pak_prefix = "monochrome"
+      }
+      if (is_trichrome) {
+        # Include placeholder libraries to make Chrome multiarch in the same way
+        # as Monochrome, even though Chrome only runs with one of the two
+        # bitnesses. This allows the "32-bit" and "64-bit" versions of Chrome to
+        # depend on their respective versions of the shared library APK even
+        # though they're functionally the same.
+        if (android_64bit_target_cpu) {
+          if (invoker.is_64_bit_browser) {
+            native_lib_placeholders += [ "libdummy.so" ]
+            if (_include_32_bit_webview) {
+              secondary_native_lib_placeholders += [ "libdummy.so" ]
+            }
+          } else {
+            secondary_native_lib_placeholders += [ "libdummy.so" ]
+            if (_include_64_bit_webview) {
+              native_lib_placeholders += [ "libdummy.so" ]
+            }
+          }
+        } else {
+          native_lib_placeholders += [ "libdummy.so" ]
+        }
+
+        _pak_prefix = "trichrome_chrome"
+      }
+
+      # The Chromium Linker depends on ASharedMemory_create() introduced in O.
+      use_chromium_linker = is_trichrome && chromium_linker_supported
+
+      if (build_hwasan_splits && android_64bit_target_cpu &&
+          invoker.is_64_bit_browser) {
+        _hwasan_toolchain =
+            "//build/toolchain/android:android_clang_arm64_hwasan"
+        shared_libraries +=
+            [ "//chrome/android:libmonochrome_64($_hwasan_toolchain)" ]
+
+        if (use_chromium_linker) {
+          shared_libraries += [
+            "//base/android/linker:chromium_android_linker($_hwasan_toolchain)",
+          ]
+        }
+      }
+
+      # We only optimize resources in bundles.
+      if (_is_bundle_module) {
+        # Resources config for blocklisting resource names from obfuscation
+        resources_config_paths = [
+          "//android_webview/aapt2.config",
+          "//chrome/android/aapt2.config",
+        ]
+        if (defined(invoker.resources_config_paths)) {
+          resources_config_paths += invoker.resources_config_paths
+        }
+      }
+
+      if (defined(invoker.never_incremental)) {
+        never_incremental = invoker.never_incremental
+      } else if (!defined(invoker.target_type) ||
+                 invoker.target_type == "android_apk") {
+        # Incremental install doesn't work for monochrome. See crbug.com/663492.
+      }
+
+      # Strip xml namespaces for monochrome. This should only be done for apks
+      # targeting API > 21 which for chrome is only Monochrome. This is due to
+      # how android public and private resource ids are namespaced.
+      if (defined(invoker.no_xml_namespaces)) {
+        no_xml_namespaces = invoker.no_xml_namespaces
+      } else {
+        no_xml_namespaces = true
+      }
+
+      if (_is_bundle_module) {
+        _pak_prefix += "_bundle_module"
+      } else {
+        _pak_prefix += "_apk"
+      }
+      deps += [ "//chrome/android:${_pak_prefix}_pak_assets" ]
+
+      if (!is_java_debug) {
+        proguard_configs = []
+        if (defined(invoker.proguard_configs)) {
+          proguard_configs += invoker.proguard_configs
+        }
+        if (is_monochrome) {
+          proguard_configs +=
+              [ "//android_webview/nonembedded/java/proguard.flags" ]
         }
       }
     }
 
-    forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
-    forward_variables_from(invoker,
-                           "*",
-                           TESTONLY_AND_VISIBILITY + [
-                                 "deps",
-                                 "shared_libraries",
-                                 "loadable_modules",
-                                 "secondary_abi_shared_libraries",
-                                 "secondary_abi_loadable_modules",
-                                 "data_deps",
-                                 "proguard_configs",
-                                 "manifest_package",
-                                 "version_code",
-                                 "assert_no_deps",
-                                 "version_name",
-                                 "resources_config_paths",
-                               ])
-  }
-}
-
-# For creating chrome targets without internal customizations.
-template("chrome_public_apk_or_module_tmpl") {
-  chrome_common_apk_or_module_tmpl(target_name) {
-    _is_trichrome = defined(invoker.is_trichrome) && invoker.is_trichrome
-    _is_monochrome = defined(invoker.is_monochrome) && invoker.is_monochrome
-    _is_bundle = invoker.target_type == "android_app_bundle_module"
-
-    deps = []
-    if (defined(invoker.deps)) {
-      deps += invoker.deps
-    }
-    if (_is_monochrome) {
-      deps += upstream_only_webview_deps
-    } else if (!_is_trichrome) {
-      deps += [
-        "//chrome/android:chrome_public_apk_base_module_resources",
-        "//chrome/android:chrome_public_base_module_java",
-        "//chrome/android:chrome_public_non_pak_assets",
-        "//components/browser_ui/styles/android:chrome_public_apk_resources",
-      ]
-    }
-    if (_is_bundle) {
-      deps += [
-        # deps in delegate_public_impl_java are put into the Chrome module, but the language deps
-        # are needed by the base module.
-        "//components/language/android:ulp_delegate_public_java",
-      ]
-    } else {
-      deps += [ "//chrome/android:delegate_public_impl_java" ]
-    }
-    forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
-    forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY + [ "deps" ])
-  }
-}
-
-# TODO(https://crbug.com/1427610): Remove.
-template("monochrome_public_common_apk_or_module_tmpl") {
-  chrome_common_apk_or_module_tmpl(target_name) {
-    forward_variables_from(invoker, "*")
-    if (!defined(is_monochrome)) {
-      is_trichrome = true
-    }
-  }
-}
-template("chrome_public_common_apk_or_module_tmpl") {
-  chrome_common_apk_or_module_tmpl(target_name) {
-    forward_variables_from(invoker, "*")
+    # The _overrides scope is used to ensure that:
+    # * Values set in invoker cannot accidentally clobber values set in
+    #   _overrides.
+    # * Values set in _overrides cannot accidentaly clobber values set in
+    #   invoker (since the forward_variables_from will fail).
+    _override_args = [
+      "alternative_android_sdk_dep",
+      "app_as_shared_lib",
+      "deps",
+      "is_monochrome",
+      "is_trichrome",
+      "isolated_splits_enabled",
+      "loadable_modules",
+      "native_lib_placeholders",
+      "never_incremental",
+      "no_xml_namespaces",
+      "product_config_java_packages",
+      "proguard_configs",
+      "resources_config_paths",
+      "secondary_abi_loadable_modules",
+      "secondary_abi_shared_libraries",
+      "secondary_native_lib_placeholders",
+      "shared_libraries",
+      "use_chromium_linker",
+      "webview_product_config_java_package",
+    ]
+    forward_variables_from(invoker, "*", _override_args)
+    forward_variables_from(_overrides, _override_args)
   }
 }
diff --git a/chrome/android/chrome_test_apk_tmpl.gni b/chrome/android/chrome_test_apk_tmpl.gni
index b9d6791..5ca00db6a 100644
--- a/chrome/android/chrome_test_apk_tmpl.gni
+++ b/chrome/android/chrome_test_apk_tmpl.gni
@@ -4,40 +4,50 @@
 
 import("//chrome/android/chrome_public_apk_tmpl.gni")
 
+# Dependencies that are common to any chrome_public derivative targets.
+chrome_public_shared_deps = [
+  "//chrome/android:chrome_app_java_resources",
+  "//chrome/android:chrome_public_apk_base_module_resources",
+  "//chrome/android:chrome_public_base_module_java",
+  "//chrome/android:chrome_public_non_pak_assets",
+  "//components/browser_ui/styles/android:chrome_public_apk_resources",
+  "//gin:v8_snapshot_assets",
+  "//third_party/icu:icu_assets",
+]
+
 chrome_public_test_manifest_package = "org.chromium.chrome.tests"
 
 template("chrome_test_apk_tmpl") {
-  chrome_common_apk_or_module_tmpl(target_name) {
+  chrome_public_common_apk_or_module_tmpl(target_name) {
     testonly = true
     target_type = "instrumentation_test_apk"
     bundles_supported = true
-
-    if (!defined(invoker.is_monochrome)) {
-      jinja_input = "//chrome/android/javatests/AndroidManifest.xml"
-      manifest_package = chrome_public_test_manifest_package
-    }
+    jinja_input = "//chrome/android/javatests/AndroidManifest.xml"
+    manifest_package = chrome_public_test_manifest_package
     shared_libraries = [ "//chrome/android:libchromefortest" ]
 
-    deps = [
-      "//chrome/android:chrome_public_base_module_java_for_test",
-      "//third_party/android_sdk:android_test_base_java",
-      "//third_party/android_sdk:android_test_mock_java",
-      "//third_party/android_sdk:android_test_runner_java",
-      "//third_party/androidx:androidx_test_runner_java",
-    ]
-    if (defined(invoker.deps)) {
-      deps += invoker.deps
-    }
+    deps = chrome_public_shared_deps + invoker.deps + [
+             "//chrome/android:chrome_apk_pak_assets",
+             "//chrome/android:chrome_public_base_module_java_for_test",
+             "//third_party/android_sdk:android_test_base_java",
+             "//third_party/android_sdk:android_test_mock_java",
+             "//third_party/android_sdk:android_test_runner_java",
+             "//third_party/androidx:androidx_test_runner_java",
+           ]
     if (add_unwind_tables_in_chrome_32bit_apk && current_cpu == "arm") {
       deps += [ "//chrome/android:libchromefortest_unwind_table_assets" ]
     }
+    if (enable_vr) {
+      # Contains VrFirstRunActivity, which is referenced by AndroidManifest.xml.
+      deps += [ "//chrome/android/features/vr:java" ]
+    }
 
-    # For EmbeddedTestServer.
     additional_apks = [ "//net/android:net_test_support_apk" ]
     if (defined(invoker.additional_apks)) {
       additional_apks += invoker.additional_apks
     }
     if (!is_java_debug) {
+      proguard_enabled = true
       proguard_configs = [ "//chrome/android/proguard/apk_for_test.flags" ]
       if (defined(invoker.proguard_configs)) {
         proguard_configs += invoker.proguard_configs
@@ -58,18 +68,54 @@
   }
 }
 
-# TODO(agrieve): Delete this and have all tests use chrome_test_apk_tmpl.
 template("monochrome_test_apk_tmpl") {
-  chrome_test_apk_tmpl(target_name) {
-    is_monochrome = true
-    manifest_package = chrome_public_manifest_package
+  monochrome_public_common_apk_or_module_tmpl(target_name) {
+    forward_variables_from(invoker,
+                           [
+                             "apk_name",
+                             "data_deps",
+                             "is_64_bit_browser",
+                             "include_64_bit_webview",
+                             "include_32_bit_webview",
+                             "loadable_modules",
+                             "proguard_configs",
+                             "secondary_abi_loadable_modules",
+                             "target_sdk_version",
+                           ])
+    testonly = true
+    target_type = "instrumentation_test_apk"
+
+    # TODO(agrieve): Add: manifest_package = chrome_public_test_manifest_package
 
     jinja_input = "//chrome/android/javatests/AndroidManifest_monochrome.xml"
     jinja_extra_includes = [ "//chrome/android/javatests/AndroidManifest.xml" ]
     jinja_extra_variables =
         [ "test_manifest_package=$chrome_public_test_manifest_package" ]
 
-    forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
-    forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
+    deps = chrome_public_shared_deps + invoker.deps + [
+             "//android_webview:platform_service_bridge_upstream_implementation_java",
+             "//chrome/android:chrome_public_base_module_java_for_test",
+             "//chrome/android:monochrome_apk_pak_assets",
+             "//third_party/android_sdk:android_test_base_java",
+             "//third_party/android_sdk:android_test_mock_java",
+             "//third_party/android_sdk:android_test_runner_java",
+             "//third_party/androidx:androidx_test_runner_java",
+           ]
+
+    if (webview_includes_weblayer) {
+      deps += [ "//weblayer/browser/java:upstream_java" ]
+    }
+
+    additional_apks = [ "//net/android:net_test_support_apk" ]
+    if (defined(invoker.additional_apks)) {
+      additional_apks += invoker.additional_apks
+    }
+    if (!is_java_debug) {
+      if (!defined(proguard_configs)) {
+        proguard_configs = []
+      }
+      proguard_enabled = true
+      proguard_configs += [ "//chrome/android/proguard/apk_for_test.flags" ]
+    }
   }
 }
diff --git a/chrome/android/java/res/layout/autofill_address_profile_prompt_source_notice.xml b/chrome/android/java/res/layout/autofill_address_profile_prompt_source_notice.xml
new file mode 100644
index 0000000..ab57ae2
--- /dev/null
+++ b/chrome/android/java/res/layout/autofill_address_profile_prompt_source_notice.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+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.
+-->
+
+<TextView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/autofill_address_profile_prompt_source_notice"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:paddingStart="@dimen/dialog_padding_sides"
+    android:textAppearance="@style/TextAppearance.TextMedium.Secondary"
+    tools:text="@string/autofill_save_in_account_prompt_address_source_notice" />
diff --git a/chrome/android/java/res/layout/autofill_migrate_address_profile_prompt.xml b/chrome/android/java/res/layout/autofill_migrate_address_profile_prompt.xml
new file mode 100644
index 0000000..59923bb
--- /dev/null
+++ b/chrome/android/java/res/layout/autofill_migrate_address_profile_prompt.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+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.
+-->
+
+<ScrollView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+  <RelativeLayout
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:focusable="true"
+      android:focusableInTouchMode="true">
+
+    <include
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/address_prompt_end_margin"
+        android:layout_marginTop="8dp"
+        android:layout_marginBottom="8dp"
+        layout="@layout/autofill_address_profile_prompt_source_notice" />
+
+    <org.chromium.ui.widget.ChromeImageButton
+        android:id="@+id/edit_button"
+        android:layout_width="@dimen/address_prompt_edit_button_size"
+        android:layout_height="@dimen/address_prompt_edit_button_size"
+        android:layout_alignParentEnd="true"
+        android:layout_marginEnd="@dimen/address_prompt_end_margin"
+        android:layout_marginTop="8dp"
+        android:layout_below="@+id/autofill_address_profile_prompt_source_notice"
+        android:padding="@dimen/address_prompt_edit_button_padding"
+        android:background="?attr/selectableItemBackground"
+        android:contentDescription="@string/autofill_save_address_prompt_edit_button_tooltip"
+        android:scaleType="fitCenter"
+        app:srcCompat="@drawable/edit_icon"
+        app:tint="@color/default_icon_color_tint_list" />
+
+    <LinearLayout
+        android:id="@+id/address_data"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/autofill_address_profile_prompt_source_notice"
+        android:layout_toStartOf="@id/edit_button"
+        android:paddingTop="12dp"
+        android:paddingStart="@dimen/dialog_padding_sides"
+        android:orientation="vertical">
+
+      <org.chromium.ui.widget.TextViewWithLeading
+          android:id="@+id/address"
+          android:layout_width="match_parent"
+          android:layout_height="wrap_content"
+          android:layout_marginBottom="12dp"
+          android:textAppearance="@style/TextAppearance.TextLarge.Secondary"
+          app:leading="@dimen/text_size_large_leading"
+          tools:text="John Doe\n1600 Amphitheatre Parkway\nMountain View,, CA, 94043\nUnited States" />
+
+      <TextView
+          android:id="@+id/email"
+          android:layout_width="match_parent"
+          android:layout_height="wrap_content"
+          android:textAppearance="@style/TextAppearance.TextLarge.Secondary"
+          tools:text="xyz@example.com" />
+
+      <TextView
+          android:id="@+id/phone"
+          android:layout_width="match_parent"
+          android:layout_height="wrap_content"
+          android:textAppearance="@style/TextAppearance.TextLarge.Secondary"
+          tools:text="+1 111 111 0000" />
+
+    </LinearLayout>
+  </RelativeLayout>
+</ScrollView>
diff --git a/chrome/android/java/res/layout/autofill_save_address_profile_prompt.xml b/chrome/android/java/res/layout/autofill_save_address_profile_prompt.xml
index 1f58d5e4..7232249 100644
--- a/chrome/android/java/res/layout/autofill_save_address_profile_prompt.xml
+++ b/chrome/android/java/res/layout/autofill_save_address_profile_prompt.xml
@@ -20,17 +20,16 @@
 
     <org.chromium.ui.widget.ChromeImageButton
         android:id="@+id/edit_button"
-        android:layout_width="48dp"
-        android:layout_height="48dp"
+        android:layout_width="@dimen/address_prompt_edit_button_size"
+        android:layout_height="@dimen/address_prompt_edit_button_size"
         android:layout_alignParentEnd="true"
-        android:layout_marginEnd="8dp"
-        android:padding="12dp"
+        android:layout_marginEnd="@dimen/address_prompt_end_margin"
+        android:padding="@dimen/address_prompt_edit_button_padding"
         android:background="?attr/selectableItemBackground"
         android:contentDescription="@string/autofill_save_address_prompt_edit_button_tooltip"
         android:scaleType="fitCenter"
         app:srcCompat="@drawable/edit_icon"
-        app:tint="@color/default_icon_color_tint_list"
-        tools:src="@drawable/edit_icon" />
+        app:tint="@color/default_icon_color_tint_list" />
 
     <LinearLayout
         android:id="@+id/address_data"
@@ -39,8 +38,7 @@
         android:layout_toStartOf="@id/edit_button"
         android:paddingTop="@dimen/dialog_padding_top"
         android:paddingStart="@dimen/dialog_padding_sides"
-        android:orientation="vertical"
-        tools:ignore="RtlSymmetry">
+        android:orientation="vertical">
 
       <org.chromium.ui.widget.TextViewWithLeading
           android:id="@+id/address"
@@ -49,21 +47,21 @@
           android:layout_marginBottom="12dp"
           android:textAppearance="@style/TextAppearance.TextLarge.Secondary"
           app:leading="@dimen/text_size_large_leading"
-          tools:text="Alex Park\n345 High Street\nSan Francisco, CA, 94105\nUnited States" />
+          tools:text="John Doe\n1600 Amphitheatre Parkway\nMountain View, CA, 94043\nUnited States" />
 
       <TextView
           android:id="@+id/email"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:textAppearance="@style/TextAppearance.TextLarge.Secondary"
-          tools:text="alex.park@gmail.com" />
+          tools:text="xyz@example.com" />
 
       <TextView
           android:id="@+id/phone"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:textAppearance="@style/TextAppearance.TextLarge.Secondary"
-          tools:text="+1 858 230 4000" />
+          tools:text="+1 111 111 0000" />
 
     </LinearLayout>
 
@@ -94,6 +92,12 @@
           android:textAppearance="@style/TextAppearance.TextLarge.Secondary" />
     </com.google.android.material.textfield.TextInputLayout>
 
-    <include layout="@layout/autofill_save_update_address_profile_prompt_footer"/>
+    <include
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/address_prompt_end_margin"
+        android:layout_marginTop="20dp"
+        android:layout_below="@+id/nickname_input_layout"
+        layout="@layout/autofill_address_profile_prompt_source_notice" />
   </RelativeLayout>
 </ScrollView>
diff --git a/chrome/android/java/res/layout/autofill_save_update_address_profile_prompt_footer.xml b/chrome/android/java/res/layout/autofill_save_update_address_profile_prompt_footer.xml
deleted file mode 100644
index 33a168f..0000000
--- a/chrome/android/java/res/layout/autofill_save_update_address_profile_prompt_footer.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-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.
--->
-
-<merge
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools">
-  <TextView
-      android:id="@+id/autofill_save_update_address_profile_prompt_footer"
-      android:layout_width="match_parent"
-      android:layout_height="wrap_content"
-      android:paddingStart="@dimen/dialog_padding_sides"
-      android:paddingTop="12dp"
-      android:paddingBottom="8dp"
-      android:textAppearance="@style/TextAppearance.TextMedium.Secondary"
-      tools:text="@string/autofill_save_in_account_prompt_address_source_notice" />
-</merge>
diff --git a/chrome/android/java/res/layout/autofill_update_address_profile_prompt.xml b/chrome/android/java/res/layout/autofill_update_address_profile_prompt.xml
index 01ec7b41..19263a74 100644
--- a/chrome/android/java/res/layout/autofill_update_address_profile_prompt.xml
+++ b/chrome/android/java/res/layout/autofill_update_address_profile_prompt.xml
@@ -20,7 +20,7 @@
       android:ellipsize="end"
       android:maxLines="1"
       android:textAppearance="@style/TextAppearance.TextMedium.Secondary"
-      tools:text="For Alex Park — 345 Spear street" />
+      tools:text="For John Doe — 1600 Amphitheatre Parkway" />
 
   <org.chromium.components.browser_ui.widget.FadingEdgeScrollView
       android:layout_width="match_parent"
@@ -38,8 +38,7 @@
       <RelativeLayout
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
-          android:paddingStart="@dimen/dialog_padding_sides"
-          tools:ignore="RtlSymmetry">
+          android:paddingStart="@dimen/dialog_padding_sides">
 
         <Space
             android:id="@+id/no_header_space"
@@ -67,23 +66,22 @@
             android:layout_toStartOf="@id/edit_button"
             android:textAppearance="@style/TextAppearance.TextLarge.Primary"
             app:leading="@dimen/text_size_large_leading"
-            tools:text="Alex Johnson Park\n+1 858 230 4000" />
+            tools:text="John Robert Doe\n+1 111 111 0000" />
 
         <org.chromium.ui.widget.ChromeImageButton
             android:id="@+id/edit_button"
-            android:layout_width="48dp"
-            android:layout_height="48dp"
+            android:layout_width="@dimen/address_prompt_edit_button_size"
+            android:layout_height="@dimen/address_prompt_edit_button_size"
             android:layout_alignBaseline="@id/details_new"
             android:layout_alignParentEnd="true"
-            android:layout_marginEnd="8dp"
+            android:layout_marginEnd="@dimen/address_prompt_end_margin"
             android:baseline="32dp"
-            android:padding="12dp"
+            android:padding="@dimen/address_prompt_edit_button_padding"
             android:background="?attr/selectableItemBackground"
             android:contentDescription="@string/autofill_save_address_prompt_edit_button_tooltip"
             android:scaleType="fitCenter"
             app:srcCompat="@drawable/edit_icon"
-            app:tint="@color/default_icon_color_tint_list"
-            tools:src="@drawable/edit_icon" />
+            app:tint="@color/default_icon_color_tint_list" />
       </RelativeLayout>
 
       <TextView
@@ -105,9 +103,14 @@
           android:paddingEnd="@dimen/dialog_padding_sides"
           android:textAppearance="@style/TextAppearance.TextLarge.Primary"
           app:leading="@dimen/text_size_large_leading"
-          tools:text="Alex Park" />
+          tools:text="John Doe" />
     </LinearLayout>
   </org.chromium.components.browser_ui.widget.FadingEdgeScrollView>
 
-  <include layout="@layout/autofill_save_update_address_profile_prompt_footer"/>
+  <include
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:layout_marginEnd="@dimen/address_prompt_end_margin"
+      android:layout_marginTop="12dp"
+      layout="@layout/autofill_address_profile_prompt_source_notice" />
 </LinearLayout>
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml
index 9ad0fea1..8723345 100644
--- a/chrome/android/java/res/values/dimens.xml
+++ b/chrome/android/java/res/values/dimens.xml
@@ -71,6 +71,11 @@
     <!-- Sheet tab toolbar dimensions -->
     <dimen name="sheet_tab_toolbar_height">70dp</dimen>
 
+    <!-- Autofill address prompt dimensions -->
+    <dimen name="address_prompt_end_margin">8dp</dimen>
+    <dimen name="address_prompt_edit_button_size">48dp</dimen>
+    <dimen name="address_prompt_edit_button_padding">12dp</dimen>
+
     <!-- Autofill keyboard accessory dimensions -->
     <dimen name="keyboard_accessory_height_with_shadow">56dp</dimen>
     <dimen name="keyboard_accessory_sheet_height">330dp</dimen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/SaveUpdateAddressProfilePrompt.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/SaveUpdateAddressProfilePrompt.java
index d090920..343df72 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/SaveUpdateAddressProfilePrompt.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/SaveUpdateAddressProfilePrompt.java
@@ -35,6 +35,7 @@
 
 /**
  * Prompt that asks users to confirm saving an address profile imported from a form submission.
+ * TODO(crbug.com/1432549): cover with render tests.
  */
 @JNINamespace("autofill")
 @JNIAdditionalImport(PersonalDataManager.class)
@@ -58,10 +59,15 @@
         mModalDialogManager = modalDialogManager;
 
         LayoutInflater inflater = LayoutInflater.from(activity);
-        mDialogView = inflater.inflate(isUpdate ? R.layout.autofill_update_address_profile_prompt
-                                                : R.layout.autofill_save_address_profile_prompt,
-                null);
-        if (!isUpdate) setupAddressNickname();
+        if (isMigrationToAccount) {
+            mDialogView = inflater.inflate(R.layout.autofill_migrate_address_profile_prompt, null);
+        } else if (isUpdate) {
+            mDialogView = inflater.inflate(R.layout.autofill_update_address_profile_prompt, null);
+        } else {
+            mDialogView = inflater.inflate(R.layout.autofill_save_address_profile_prompt, null);
+        }
+
+        if (!isUpdate && !isMigrationToAccount) setupAddressNickname();
 
         PropertyModel.Builder builder =
                 new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS)
@@ -146,7 +152,7 @@
     @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
     void setSourceNotice(String sourceNotice) {
         showTextIfNotEmpty(
-                mDialogView.findViewById(R.id.autofill_save_update_address_profile_prompt_footer),
+                mDialogView.findViewById(R.id.autofill_address_profile_prompt_source_notice),
                 sourceNotice);
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AddressEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AddressEditor.java
index 8dbdc43..cc71ac16b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AddressEditor.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AddressEditor.java
@@ -448,7 +448,10 @@
                     .replace("$1", email);
         }
 
-        return mContext.getString(R.string.autofill_address_will_be_saved_in_account_source_notice)
+        return mContext
+                .getString(mIsMigrationToAccount
+                                ? R.string.autofill_address_will_be_migrated_to_account_source_notice
+                                : R.string.autofill_address_will_be_saved_in_account_source_notice)
                 .replace("$1", email);
     }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderTest.java
index 33b80b5b..6195f177 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderTest.java
@@ -23,7 +23,6 @@
 import org.chromium.base.test.util.CriteriaHelper;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RequiresRestart;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.tab.Tab;
@@ -31,7 +30,6 @@
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
 import org.chromium.chrome.test.batch.BlankCTATabInitialStateRule;
 import org.chromium.chrome.test.util.OmniboxTestUtils;
-import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
 import org.chromium.chrome.test.util.browser.LocationSettingsTestUtil;
 import org.chromium.components.browser_ui.site_settings.PermissionInfo;
 import org.chromium.components.content_settings.ContentSettingValues;
@@ -44,7 +42,6 @@
  */
 @RunWith(ChromeJUnit4ClassRunner.class)
 @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
-@DisableFeatures({ChromeFeatureList.OPTIMIZE_GEOLOCATION_HEADER_GENERATION})
 @Batch(Batch.PER_CLASS)
 public class GeolocationHeaderTest {
     public @ClassRule static ChromeTabbedActivityTestRule sActivityTestRule =
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/SaveUpdateAddressProfilePromptTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/SaveUpdateAddressProfilePromptTest.java
index b5085838..dbefba7 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/SaveUpdateAddressProfilePromptTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/SaveUpdateAddressProfilePromptTest.java
@@ -91,10 +91,14 @@
     }
 
     private void createAndShowPrompt(boolean isUpdate) {
+        createAndShowPrompt(isUpdate, NO_MIGRATION);
+    }
+
+    private void createAndShowPrompt(boolean isUpdate, boolean isMigrationToAccount) {
         AutofillProfile dummyProfile = new AutofillProfile();
         mModalDialogManager = new FakeModalDialogManager(ModalDialogType.APP);
         mPrompt = new SaveUpdateAddressProfilePrompt(mPromptController, mModalDialogManager,
-                mActivity, mProfile, dummyProfile, isUpdate, NO_MIGRATION);
+                mActivity, mProfile, dummyProfile, isUpdate, isMigrationToAccount);
         mPrompt.setAddressEditorForTesting(mAddressEditor);
         mPrompt.show();
     }
@@ -170,10 +174,29 @@
                 propertyModel.get(ModalDialogProperties.POSITIVE_BUTTON_TEXT));
         Assert.assertEquals("negative button text",
                 propertyModel.get(ModalDialogProperties.NEGATIVE_BUTTON_TEXT));
+    }
+
+    @Test
+    @SmallTest
+    public void dialogStrings_SourceNotice() {
+        createAndShowPrompt(false, true);
+        View dialog = mPrompt.getDialogViewForTesting();
+
+        mPrompt.setSourceNotice(null);
+        Assert.assertEquals(View.GONE,
+                dialog.findViewById(R.id.autofill_address_profile_prompt_source_notice)
+                        .getVisibility());
+
+        mPrompt.setSourceNotice("");
+        Assert.assertEquals(View.GONE,
+                dialog.findViewById(R.id.autofill_address_profile_prompt_source_notice)
+                        .getVisibility());
 
         mPrompt.setSourceNotice("source notice");
-        validateTextView(
-                dialog.findViewById(R.id.autofill_save_update_address_profile_prompt_footer),
+        Assert.assertEquals(View.VISIBLE,
+                dialog.findViewById(R.id.autofill_address_profile_prompt_source_notice)
+                        .getVisibility());
+        validateTextView(dialog.findViewById(R.id.autofill_address_profile_prompt_source_notice),
                 "source notice");
     }
 
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/AddressEditorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/AddressEditorTest.java
index 142dd19..678bc80c 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/AddressEditorTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/AddressEditorTest.java
@@ -470,7 +470,8 @@
                         .replace("$1", USER_EMAIL);
         final String sourceNotice =
                 mActivity
-                        .getString(R.string.autofill_address_will_be_saved_in_account_source_notice)
+                        .getString(
+                                R.string.autofill_address_will_be_migrated_to_account_source_notice)
                         .replace("$1", USER_EMAIL);
 
         checkUiStringsHaveExpectedValues(
diff --git a/chrome/android/trichrome.gni b/chrome/android/trichrome.gni
index c693f23..32ebe22 100644
--- a/chrome/android/trichrome.gni
+++ b/chrome/android/trichrome.gni
@@ -44,14 +44,6 @@
        invoker.include_64_bit_webview) && android_64bit_target_cpu
   _include_32_bit_webview =
       !defined(invoker.include_32_bit_webview) || invoker.include_32_bit_webview
-  _include_primary_abi =
-      !android_64bit_target_cpu || _is_64_bit_browser || _include_64_bit_webview
-  _include_secondary_abi = android_64bit_target_cpu &&
-                           (!_is_64_bit_browser || _include_32_bit_webview)
-  if (_include_secondary_abi) {
-    _secondary_out_dir =
-        get_label_info("X($android_secondary_abi_toolchain)", "root_out_dir")
-  }
   _version_code = TRICHROME_VERSION_MAP["${android_64bit_target_cpu}_${_is_64_bit_browser}_${_include_64_bit_webview}_${_include_32_bit_webview}"]
 
   # TODO(crbug.com/1411557): Remove option for custom manifest.
@@ -95,35 +87,40 @@
       expected_android_manifest_library_version_offset = chrome_version_code
     }
 
-    omit_dex = true
+    # TODO(torne): since there's no real java code in the library right now,
+    # leave out the build hooks and let them get compiled into each APK. Later
+    # this should probably be in the library.
+    no_build_hooks = true
     include_size_info = is_official_build
+
     alternative_android_sdk_dep = webview_framework_dep
     r_java_root_package_name = "trichrome_lib"
     app_as_shared_lib = true
-    version_name = chrome_version_name
-    version_code = _version_code
-    min_sdk_version = 29
 
     # No support for this has been added, also not supported by test runner
     # since trichrome library is used in "additional_apks" in the trichrome
     # bundle smoke tests.
     never_incremental = true
 
+    version_name = chrome_version_name
+    version_code = _version_code
+    min_sdk_version = 29
+
     # TODO(torne): using icon_resources just to get a temporary icon
     deps = [
       "//android_webview/nonembedded:icon_resources",
       "//third_party/icu:icu_assets",
     ]
-    if (_include_primary_abi) {
-      deps += [ "//gin:v8_snapshot_assets" ]
-    }
-    if (_include_secondary_abi) {
-      deps += [ "//gin:v8_snapshot_secondary_abi_assets" ]
-    }
     if (defined(invoker.deps)) {
       deps += invoker.deps
     }
 
+    omit_dex = true
+
+    # Flag whether additional deps and libs should be included for each ABI.
+    _include_primary_support = false
+    _include_secondary_support = false
+
     if (android_64bit_target_cpu) {
       # Include the actual browser-bitness libmonochrome library, dependencies
       # (crashpad and linker), and an opposite-bitness placeholder library to
@@ -131,54 +128,64 @@
       # precompiled for both architectures.
       if (_is_64_bit_browser) {
         shared_libraries = [ "//chrome/android:libmonochrome_64" ]
+        _include_primary_support = true
         if (_include_32_bit_webview) {
           secondary_native_lib_placeholders = [ "libdummy.so" ]
         }
-        if (build_hwasan_splits) {
-          _hwasan_toolchain =
-              "//build/toolchain/android:android_clang_arm64_hwasan"
-          shared_libraries +=
-              [ "//chrome/android:libmonochrome_64($_hwasan_toolchain)" ]
-        }
       } else {
         secondary_abi_shared_libraries =
             [ "//chrome/android:monochrome_secondary_abi_lib" ]
+        _include_secondary_support = true
         if (invoker.include_64_bit_webview) {
           native_lib_placeholders = [ "libdummy.so" ]
         }
       }
     } else {
       shared_libraries = [ "//chrome/android:libmonochrome" ]
+      _include_primary_support = true
     }
 
-    # https://chromium.googlesource.com/chromium/src/+/main/docs/android_native_libraries.md#Crashpad-Packaging
-    loadable_modules = []
-    secondary_abi_loadable_modules = []
-    if (_include_primary_abi) {
+    if (_include_primary_support) {
       deps += [
+        "//gin:v8_snapshot_assets",
         "//third_party/crashpad/crashpad/handler:crashpad_handler_trampoline",
       ]
-      loadable_modules += [ "$root_out_dir/libcrashpad_handler_trampoline.so" ]
+      loadable_modules = [ "$root_out_dir/libcrashpad_handler_trampoline.so" ]
     }
-    if (_include_secondary_abi) {
-      deps += [ "//third_party/crashpad/crashpad/handler:crashpad_handler_trampoline($android_secondary_abi_toolchain)" ]
-      secondary_abi_loadable_modules +=
+    if (_include_secondary_support) {
+      _trampoline =
+          "//third_party/crashpad/crashpad/handler:" +
+          "crashpad_handler_trampoline($android_secondary_abi_toolchain)"
+      deps += [
+        "//gin:v8_snapshot_secondary_abi_assets",
+        _trampoline,
+      ]
+      _secondary_out_dir = get_label_info(_trampoline, "root_out_dir")
+      secondary_abi_loadable_modules =
           [ "$_secondary_out_dir/libcrashpad_handler_trampoline.so" ]
     }
 
     if (enable_arcore) {
-      _arcore_target = "//third_party/arcore-android-sdk-client:com_google_ar_core_J__unpack_aar"
-      _libarcore_dir = get_label_info(_arcore_target, "target_out_dir") +
-                       "/com_google_ar_core_java/jni"
-      deps += [ "//third_party/arcore-android-sdk-client:com_google_ar_core_J__unpack_aar" ]
+      _libarcore_dir = get_label_info(
+                           "//third_party/arcore-android-sdk-client:com_google_ar_core_java($default_toolchain)",
+                           "target_out_dir") + "/com_google_ar_core_java/jni"
+      not_needed([ "_libarcore_dir" ])
 
-      if (_include_primary_abi) {
+      _arcore_extra_deps = [ "//third_party/arcore-android-sdk-client:com_google_ar_core_J__unpack_aar" ]
+      not_needed([ "_arcore_extra_deps" ])
+
+      if (_include_primary_support) {
         loadable_modules +=
             [ "$_libarcore_dir/$android_app_abi/libarcore_sdk_c.so" ]
+        deps += _arcore_extra_deps
       }
-      if (_include_secondary_abi) {
-        secondary_abi_loadable_modules +=
-            [ "$_libarcore_dir/$android_app_secondary_abi/libarcore_sdk_c.so" ]
+      if (_include_secondary_support) {
+        if (enable_arcore) {
+          secondary_abi_loadable_modules += [
+            "$_libarcore_dir/$android_app_secondary_abi/libarcore_sdk_c.so",
+          ]
+          deps += _arcore_extra_deps
+        }
       }
     }
     forward_variables_from(invoker,
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd
index ef67dd3..7e1d696 100644
--- a/chrome/app/chromium_strings.grd
+++ b/chrome/app/chromium_strings.grd
@@ -809,6 +809,12 @@
         </message>
       </if>
 
+      <if expr="is_win or is_macosx or is_linux">
+        <message name="IDS_RELAUNCH_TO_UPDATE_ALT" desc="Alternate text label of the relaunch to update Chrome menu item" translateable="false">
+        Not used in Chromium. Placeholder to keep resource maps in sync.
+        </message>
+      </if>
+
       <if expr="is_macosx">
         <message name="IDS_APP_MENU_PRODUCT_NAME" desc="The application's short name, used for the Mac's application menu, activity monitor, etc. This should be less than 16 characters. Example: Chrome, not Google Chrome.">
           Chromium
@@ -1151,6 +1157,15 @@
         </message>
       </if>
 
+      <if expr="is_win or is_macosx or is_linux">
+        <message name="IDS_UPDATE_RECOMMENDED_DIALOG_TITLE_ALT" desc="Alternate window title for the Update Recommended dialog." translateable="false">
+          Not used in Chromium. Placeholder to keep resource maps in sync.
+        </message>
+        <message name="IDS_UPDATE_RECOMMENDED_ALT" desc="Alternate main text of the Update Recommended dialog with a count of open Incognito windows." translateable="false">
+          Not used in Chromium. Placeholder to keep resource maps in sync.
+        </message>
+      </if>
+
       <!-- Update bubble -->
       <message name="IDS_REINSTALL_APP" desc="Text for the button the user clicks to reinstall the app.">
         Reinstall Chromium
@@ -1663,16 +1678,6 @@
       <!-- High Efficiency IPH strings -->
       <if expr="not is_android">
         <if expr="use_titlecase">
-          <message name="IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TITLE" desc="In Title Case: The title for the high efficiency info mode in-product promo bubble.">
-            Memory Saver Made Chromium Faster
-          </message>
-        </if>
-        <if expr="not use_titlecase">
-          <message name="IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TITLE" desc="The title for the high efficiency info mode in-product promo bubble.">
-            Memory Saver made Chromium faster
-          </message>
-        </if>
-        <if expr="use_titlecase">
           <message name="IDS_HIGH_EFFICIENCY_MODE_PROMO_TITLE" desc="In Title Case: The title for the high efficiency mode in-product promo bubble">
             Make Chromium Faster
           </message>
diff --git a/chrome/app/chromium_strings_grd/IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TITLE.png.sha1 b/chrome/app/chromium_strings_grd/IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TITLE.png.sha1
deleted file mode 100644
index 57350014..0000000
--- a/chrome/app/chromium_strings_grd/IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TITLE.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-eaa33f2365a0520981c4befc57752f11bcb7c169
\ No newline at end of file
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index daaefb1..eae13c0b 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -7113,6 +7113,9 @@
       <message name="IDS_NTP_MODULES_CART_LOWER_YOUR" desc="Name of the chrome cart module in lowercase shown in various UIs.">
         your carts
       </message>
+      <message name="IDS_NTP_MODULES_QUEST_CART_ANNOTATION" desc="Annotation that shows in the ChromeCart tile in Quest module to let users know that this tile is from pending items in their shopping cart.">
+        In your cart
+      </message>
       <message name="IDS_NTP_MODULES_CART_INFO" desc="Text shown in the body of the info dialog of the cart module.">
         You’re seeing carts that help you easily get back to items you left in shopping carts across the web.
         <ph name="BREAK">&lt;br&gt;</ph>
@@ -8215,12 +8218,6 @@
       <message name="IDS_BATTERY_SAVER_MODE_PROMO_ACTION_TEXT" desc="The custom action button text for the battery saver mode in-product promo bubble.">
         Settings
       </message>
-      <message name="IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TEXT" desc="The text shown for the high efficiency info mode in-product promo bubble.">
-        While this tab was inactive, Memory Saver freed up memory for other tasks. You can change this anytime in settings.
-      </message>
-      <message name="IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_ACTION_TEXT" desc="The custom action button text for the high efficiency info mode in-product promo bubble.">
-        Settings
-      </message>
       <if expr="use_titlecase">
         <message name="IDS_HIGH_EFFICIENCY_MODE_PROMO_TEXT" desc="The text shown for the high efficiency mode in-product promo bubble">
           Memory Saver frees up memory from inactive tabs so it can be used by active tabs and other apps.
@@ -9424,6 +9421,17 @@
       <message name="IDS_APP_MENU_BUTTON_UPDATE" desc="Short label next to app-menu button when an update is available.">
         Update
       </message>
+      <if expr="is_win or is_macosx or is_linux">
+        <message name="IDS_APP_MENU_BUTTON_UPDATE_ALT1" desc="Alternate short label next to app-menu button when an update is available.">
+          Finish update
+        </message>
+        <message name="IDS_APP_MENU_BUTTON_UPDATE_ALT2" desc="Alternate short label next to app-menu button when an update is available.">
+          Relaunch to update
+        </message>
+        <message name="IDS_APP_MENU_BUTTON_UPDATE_ALT3" desc="Alternate short label next to app-menu button when an update is available.">
+          New Chrome available
+        </message>
+      </if>
       <message name="IDS_APP_MENU_BUTTON_ERROR" desc="Short label next to app-menu button when the user needs to resolve something.">
         Error
       </message>
diff --git a/chrome/app/generated_resources_grd/IDS_APP_MENU_BUTTON_UPDATE_ALT1.png.sha1 b/chrome/app/generated_resources_grd/IDS_APP_MENU_BUTTON_UPDATE_ALT1.png.sha1
new file mode 100644
index 0000000..d7cea84b
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_APP_MENU_BUTTON_UPDATE_ALT1.png.sha1
@@ -0,0 +1 @@
+1fac87ea606325d799531ef8259ba0fe70160b09
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_APP_MENU_BUTTON_UPDATE_ALT2.png.sha1 b/chrome/app/generated_resources_grd/IDS_APP_MENU_BUTTON_UPDATE_ALT2.png.sha1
new file mode 100644
index 0000000..5a6b1f0
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_APP_MENU_BUTTON_UPDATE_ALT2.png.sha1
@@ -0,0 +1 @@
+5692a2825f4a8a23c74e6f8748262c5aa4ed4afd
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_APP_MENU_BUTTON_UPDATE_ALT3.png.sha1 b/chrome/app/generated_resources_grd/IDS_APP_MENU_BUTTON_UPDATE_ALT3.png.sha1
new file mode 100644
index 0000000..584487b
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_APP_MENU_BUTTON_UPDATE_ALT3.png.sha1
@@ -0,0 +1 @@
+9f7a1df62265c683ec4715ce2aca59fc4ace2382
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_ACTION_TEXT.png.sha1 b/chrome/app/generated_resources_grd/IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_ACTION_TEXT.png.sha1
deleted file mode 100644
index 57350014..0000000
--- a/chrome/app/generated_resources_grd/IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_ACTION_TEXT.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-eaa33f2365a0520981c4befc57752f11bcb7c169
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TEXT.png.sha1 b/chrome/app/generated_resources_grd/IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TEXT.png.sha1
deleted file mode 100644
index a62c876..0000000
--- a/chrome/app/generated_resources_grd/IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TEXT.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-e67acd8cde024be973d3cc91ee0a51fe09424138
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_MODULES_QUEST_CART_ANNOTATION.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_MODULES_QUEST_CART_ANNOTATION.png.sha1
new file mode 100644
index 0000000..56cfdb39
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_NTP_MODULES_QUEST_CART_ANNOTATION.png.sha1
@@ -0,0 +1 @@
+e8fc28f080b143a15e0697e7af6e8619b450e155
\ No newline at end of file
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd
index 0b81272..15ee610 100644
--- a/chrome/app/google_chrome_strings.grd
+++ b/chrome/app/google_chrome_strings.grd
@@ -840,6 +840,19 @@
         </if>
       </if>
 
+      <if expr="is_win or is_macosx or is_linux">
+        <if expr="use_titlecase">
+          <message name="IDS_RELAUNCH_TO_UPDATE_ALT" desc="Alternate text label of the relaunch to update Chrome menu item">
+            Relaunch to Update - Your tabs will reopen
+          </message>
+        </if>
+        <if expr="not use_titlecase">
+          <message name="IDS_RELAUNCH_TO_UPDATE_ALT" desc="Alternate text label of the relaunch to update Chrome menu item">
+            Relaunch to update - your tabs will reopen
+          </message>
+        </if>
+      </if>
+
       <if expr="is_macosx">
         <message name="IDS_APP_MENU_PRODUCT_NAME" desc="The application's short name, used for the Mac's application menu, activity monitor, etc. This should be less than 16 characters. Example: Chrome, not Google Chrome.">
           Chrome
@@ -1222,6 +1235,18 @@
         </message>
       </if>
 
+      <if expr="is_win or is_macosx or is_linux">
+        <message name="IDS_UPDATE_RECOMMENDED_DIALOG_TITLE_ALT" desc="Alternate window title for the Update Recommended dialog.">
+          Relaunch to finish Chrome update
+        </message>
+        <message name="IDS_UPDATE_RECOMMENDED_ALT" desc="Alternate main text of the Update Recommended dialog with a count of open Incognito windows.">
+          {COUNT, plural,
+           =0 {Chrome is done updating. You can use the latest version as soon as you relaunch. After, your current tabs will reopen.}
+           =1 {Chrome is done updating. You can use the latest version as soon as you relaunch. After, your current tabs will reopen. Your Incognito window won't reopen.}
+          other {Chrome is done updating. You can use the latest version as soon as you relaunch. After, your current tabs will reopen. Your # Incognito windows won't reopen.}}
+        </message>
+      </if>
+
       <!-- Update bubble -->
       <message name="IDS_REINSTALL_APP" desc="Text for the button the user clicks to reinstall the app.">
         Reinstall Chrome
@@ -1754,16 +1779,6 @@
       <!-- High Efficiency IPH strings -->
       <if expr="not is_android">
         <if expr="use_titlecase">
-          <message name="IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TITLE" desc="In Title Case: The title for the high efficiency info mode in-product promo bubble.">
-            Memory Saver Made Chrome Faster
-          </message>
-        </if>
-        <if expr="not use_titlecase">
-          <message name="IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TITLE" desc="The title for the high efficiency info mode in-product promo bubble.">
-            Memory Saver made Chrome faster
-          </message>
-        </if>
-        <if expr="use_titlecase">
           <message name="IDS_HIGH_EFFICIENCY_MODE_PROMO_TITLE" desc="In Title Case: The title for the high efficiency mode in-product promo bubble">
             Make Chrome Faster
           </message>
diff --git a/chrome/app/google_chrome_strings_grd/IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TITLE.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TITLE.png.sha1
deleted file mode 100644
index c9923a4..0000000
--- a/chrome/app/google_chrome_strings_grd/IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TITLE.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-0f37ea118551945bad92e6bde0773b369114d6ff
\ No newline at end of file
diff --git a/chrome/app/google_chrome_strings_grd/IDS_RELAUNCH_TO_UPDATE_ALT.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_RELAUNCH_TO_UPDATE_ALT.png.sha1
new file mode 100644
index 0000000..9b37dc5
--- /dev/null
+++ b/chrome/app/google_chrome_strings_grd/IDS_RELAUNCH_TO_UPDATE_ALT.png.sha1
@@ -0,0 +1 @@
+84f4e2d903db457de773ed4f64c91da4b03d8257
\ No newline at end of file
diff --git a/chrome/app/google_chrome_strings_grd/IDS_UPDATE_RECOMMENDED_ALT.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_UPDATE_RECOMMENDED_ALT.png.sha1
new file mode 100644
index 0000000..9c0bbef
--- /dev/null
+++ b/chrome/app/google_chrome_strings_grd/IDS_UPDATE_RECOMMENDED_ALT.png.sha1
@@ -0,0 +1 @@
+43c15cefa091a229407f18c12b0026d4c0abf977
\ No newline at end of file
diff --git a/chrome/app/google_chrome_strings_grd/IDS_UPDATE_RECOMMENDED_DIALOG_TITLE_ALT.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_UPDATE_RECOMMENDED_DIALOG_TITLE_ALT.png.sha1
new file mode 100644
index 0000000..c05a802
--- /dev/null
+++ b/chrome/app/google_chrome_strings_grd/IDS_UPDATE_RECOMMENDED_DIALOG_TITLE_ALT.png.sha1
@@ -0,0 +1 @@
+16e4a1d3a5391eb7f5bfe1abf45675fb29a81797
\ No newline at end of file
diff --git a/chrome/app/vector_icons/BUILD.gn b/chrome/app/vector_icons/BUILD.gn
index c896c4e..0ace4ced 100644
--- a/chrome/app/vector_icons/BUILD.gn
+++ b/chrome/app/vector_icons/BUILD.gn
@@ -82,6 +82,7 @@
     "input.icon",
     "journeys.icon",
     "key.icon",
+    "key_chrome_refresh.icon",
     "keyboard_arrow_down.icon",
     "keyboard_arrow_right.icon",
     "keyboard_arrow_up.icon",
@@ -187,6 +188,7 @@
     "text_increase.icon",
     "trailing_scroll.icon",
     "translate.icon",
+    "translate_chrome_refresh.icon",
     "trash_can.icon",
     "trash_can_light.icon",
     "tv.icon",
diff --git a/chrome/app/vector_icons/key_chrome_refresh.icon b/chrome/app/vector_icons/key_chrome_refresh.icon
new file mode 100644
index 0000000..9465ddf
--- /dev/null
+++ b/chrome/app/vector_icons/key_chrome_refresh.icon
@@ -0,0 +1,49 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+CANVAS_DIMENSIONS, 20,
+MOVE_TO, 6, 15,
+R_CUBIC_TO, -1.39f, 0, -2.57f, -0.49f, -3.54f, -1.46f,
+CUBIC_TO, 1.49f, 12.57f, 1, 11.39f, 1, 10,
+R_CUBIC_TO, 0, -1.39f, 0.49f, -2.57f, 1.46f, -3.54f,
+CUBIC_TO, 3.43f, 5.49f, 4.61f, 5, 6, 5,
+R_CUBIC_TO, 1, 0, 1.92f, 0.27f, 2.77f, 0.8f,
+R_CUBIC_TO, 0.85f, 0.53f, 1.45f, 1.27f, 1.81f, 2.2f,
+H_LINE_TO, 19,
+R_V_LINE_TO, 4,
+R_H_LINE_TO, -2,
+R_V_LINE_TO, 3,
+R_H_LINE_TO, -4,
+R_V_LINE_TO, -3,
+R_H_LINE_TO, -2.42f,
+R_ARC_TO, 4.62f, 4.62f, 0, 0, 1, -1.82f, 2.2f,
+CUBIC_TO, 7.92f, 14.73f, 7, 15, 6, 15,
+CLOSE,
+R_MOVE_TO, 0, -1.5f,
+R_CUBIC_TO, 0.86f, 0, 1.61f, -0.28f, 2.25f, -0.85f,
+R_CUBIC_TO, 0.64f, -0.57f, 1.06f, -1.28f, 1.25f, -2.15f,
+R_H_LINE_TO, 5,
+R_V_LINE_TO, 3,
+R_H_LINE_TO, 1,
+R_V_LINE_TO, -3,
+R_H_LINE_TO, 2,
+R_V_LINE_TO, -1,
+R_H_LINE_TO, -8,
+R_CUBIC_TO, -0.19f, -0.86f, -0.61f, -1.58f, -1.25f, -2.15f,
+CUBIC_TO_SHORTHAND, 6.86f, 6.5f, 6, 6.5f,
+R_CUBIC_TO, -0.97f, 0, -1.8f, 0.34f, -2.48f, 1.02f,
+CUBIC_TO_SHORTHAND, 2.5f, 9.03f, 2.5f, 10,
+R_CUBIC_TO, 0, 0.97f, 0.34f, 1.8f, 1.02f, 2.48f,
+CUBIC_TO_SHORTHAND, 5.03f, 13.5f, 6, 13.5f,
+CLOSE,
+MOVE_TO, 6, 12,
+R_CUBIC_TO, 0.55f, 0, 1.02f, -0.2f, 1.41f, -0.59f,
+R_CUBIC_TO, 0.39f, -0.39f, 0.59f, -0.86f, 0.59f, -1.41f,
+R_CUBIC_TO, 0, -0.55f, -0.2f, -1.02f, -0.59f, -1.41f,
+CUBIC_TO, 7.02f, 8.2f, 6.55f, 8, 6, 8,
+R_CUBIC_TO, -0.55f, 0, -1.02f, 0.2f, -1.41f, 0.59f,
+CUBIC_TO, 4.2f, 8.98f, 4, 9.45f, 4, 10,
+R_CUBIC_TO, 0, 0.55f, 0.2f, 1.02f, 0.59f, 1.41f,
+R_CUBIC_TO, 0.39f, 0.39f, 0.86f, 0.59f, 1.41f, 0.59f,
+CLOSE
diff --git a/chrome/app/vector_icons/translate_chrome_refresh.icon b/chrome/app/vector_icons/translate_chrome_refresh.icon
index 574af77..e839a51 100644
--- a/chrome/app/vector_icons/translate_chrome_refresh.icon
+++ b/chrome/app/vector_icons/translate_chrome_refresh.icon
@@ -2,73 +2,46 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-CANVAS_DIMENSIONS, 16,
-MOVE_TO, 13.6f, 3.1f,
-LINE_TO, 7.22f, 3.1f,
-LINE_TO, 6.6f, 1,
-LINE_TO, 2.4f, 1,
-CUBIC_TO, 1.63f, 1, 1, 1.63f, 1, 2.4f,
-LINE_TO, 1, 11.5f,
-CUBIC_TO, 1, 12.27f, 1.63f, 12.9f, 2.4f, 12.9f,
-LINE_TO, 7.3f, 12.9f,
-LINE_TO, 8, 15,
-LINE_TO, 13.6f, 15,
-CUBIC_TO, 14.37f, 15, 15, 14.37f, 15, 13.6f,
-LINE_TO, 15, 4.5f,
-CUBIC_TO, 15, 3.73f, 14.37f, 3.1f, 13.6f, 3.1f,
-LINE_TO, 13.6f, 3.1f,
+CANVAS_DIMENSIONS, 20,
+R_MOVE_TO, 10.17f, 18,
+R_LINE_TO, 3.56f, -9.5f,
+R_H_LINE_TO, 1.71f,
+LINE_TO, 19, 18,
+R_H_LINE_TO, -1.65f,
+R_LINE_TO, -0.85f, -2.44f,
+R_H_LINE_TO, -3.83f,
+LINE_TO, 11.82f, 18,
+R_H_LINE_TO, -1.65f,
 CLOSE,
-MOVE_TO, 4.62f, 9.81f,
-CUBIC_TO, 3.04f, 9.81f, 1.76f, 8.53f, 1.76f, 6.95f,
-CUBIC_TO, 1.76f, 5.37f, 3.04f, 4.09f, 4.62f, 4.09f,
-CUBIC_TO, 5.35f, 4.09f, 6.01f, 4.35f, 6.54f, 4.84f,
-LINE_TO, 6.59f, 4.88f,
-LINE_TO, 5.73f, 5.7f,
-LINE_TO, 5.68f, 5.67f,
-CUBIC_TO, 5.48f, 5.48f, 5.14f, 5.26f, 4.62f, 5.26f,
-CUBIC_TO, 3.7f, 5.26f, 2.95f, 6.02f, 2.95f, 6.95f,
-CUBIC_TO, 2.95f, 7.88f, 3.7f, 8.64f, 4.62f, 8.64f,
-CUBIC_TO, 5.58f, 8.64f, 5.99f, 8.04f, 6.1f, 7.62f,
-LINE_TO, 4.56f, 7.62f,
-LINE_TO, 4.56f, 6.54f,
-LINE_TO, 7.32f, 6.54f,
-LINE_TO, 7.33f, 6.59f,
-CUBIC_TO, 7.36f, 6.73f, 7.36f, 6.87f, 7.36f, 7.01f,
-CUBIC_TO, 7.36f, 8.66f, 6.24f, 9.81f, 4.62f, 9.81f,
-LINE_TO, 4.62f, 9.81f,
+R_MOVE_TO, 3, -3.81f,
+H_LINE_TO, 16,
+R_LINE_TO, -1.38f, -3.94f,
+R_H_LINE_TO, -0.08f,
+R_LINE_TO, -1.38f, 3.94f,
 CLOSE,
-MOVE_TO, 8.84f, 8.62f,
-CUBIC_TO, 9.07f, 9.04f, 9.36f, 9.44f, 9.67f, 9.81f,
-LINE_TO, 9.3f, 10.18f,
-LINE_TO, 8.84f, 8.62f,
-LINE_TO, 8.84f, 8.62f,
-CLOSE,
-MOVE_TO, 13.6f, 14.3f,
-LINE_TO, 8.7f, 14.3f,
-LINE_TO, 10.1f, 12.9f,
-LINE_TO, 9.53f, 10.96f,
-LINE_TO, 10.18f, 10.32f,
-LINE_TO, 12.05f, 12.2f,
-LINE_TO, 12.56f, 11.69f,
-LINE_TO, 10.67f, 9.81f,
-CUBIC_TO, 11.3f, 9.09f, 11.79f, 8.24f, 12.01f, 7.36f,
-LINE_TO, 12.9f, 7.36f,
-LINE_TO, 12.9f, 6.63f,
-LINE_TO, 10.35f, 6.63f,
-LINE_TO, 10.35f, 5.9f,
-LINE_TO, 9.62f, 5.9f,
-LINE_TO, 9.62f, 6.63f,
-LINE_TO, 8.25f, 6.63f,
-LINE_TO, 7.43f, 3.8f,
-LINE_TO, 13.6f, 3.8f,
-CUBIC_TO, 13.99f, 3.8f, 14.3f, 4.12f, 14.3f, 4.5f,
-LINE_TO, 14.3f, 13.6f,
-CUBIC_TO, 14.3f, 13.99f, 13.99f, 14.3f, 13.6f, 14.3f,
-CLOSE,
-MOVE_TO, 8.69f, 8.08f,
-LINE_TO, 8.47f, 7.36f,
-LINE_TO, 11.26f, 7.36f,
-CUBIC_TO, 11.26f, 7.36f, 11.02f, 8.27f, 10.17f, 9.27f,
-CUBIC_TO, 9.81f, 8.84f, 9.55f, 8.41f, 9.38f, 8.08f,
-LINE_TO, 8.69f, 8.08f,
+MOVE_TO, 3.52f, 15.5f,
+R_LINE_TO, -1.04f, -1.06f,
+R_LINE_TO, 4, -3.96f,
+R_CUBIC_TO, -0.5f, -0.53f, -0.97f, -1.08f, -1.4f, -1.65f,
+R_CUBIC_TO, -0.43f, -0.57f, -0.81f, -1.19f, -1.13f, -1.85f,
+R_H_LINE_TO, 1.71f,
+R_CUBIC_TO, 0.25f, 0.44f, 0.53f, 0.86f, 0.85f, 1.25f,
+R_CUBIC_TO, 0.32f, 0.39f, 0.65f, 0.77f, 0.98f, 1.15f,
+R_CUBIC_TO, 0.53f, -0.58f, 1.01f, -1.19f, 1.46f, -1.82f,
+R_CUBIC_TO, 0.45f, -0.63f, 0.81f, -1.32f, 1.08f, -2.05f,
+H_LINE_TO, 1,
+R_V_LINE_TO, -1.5f,
+R_H_LINE_TO, 5.75f,
+V_LINE_TO, 2,
+R_H_LINE_TO, 1.5f,
+R_V_LINE_TO, 2,
+H_LINE_TO, 14,
+R_V_LINE_TO, 1.5f,
+R_H_LINE_TO, -2.38f,
+R_CUBIC_TO, -0.29f, 0.96f, -0.72f, 1.84f, -1.27f, 2.66f,
+R_CUBIC_TO, -0.56f, 0.81f, -1.17f, 1.59f, -1.83f, 2.32f,
+R_LINE_TO, 1.9f, 1.88f,
+R_LINE_TO, -0.58f, 1.54f,
+R_LINE_TO, -2.33f, -2.33f,
+R_LINE_TO, -3.98f, 3.94f,
 CLOSE
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index f59b9a4..ca38016 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -7443,16 +7443,14 @@
       "supervised_user/supervised_user_settings_service_factory.h",
     ]
     if (is_chromeos_ash) {
-      sources += [
-        "supervised_user/chromeos/web_content_handler_impl.cc",
-        "supervised_user/chromeos/web_content_handler_impl.h",
-      ]
       deps += [ "//chrome/browser/ash/crosapi" ]
     }
     if (is_chromeos) {
       sources += [
         "supervised_user/chromeos/supervised_user_favicon_request_handler.cc",
         "supervised_user/chromeos/supervised_user_favicon_request_handler.h",
+        "supervised_user/chromeos/web_content_handler_impl.cc",
+        "supervised_user/chromeos/web_content_handler_impl.h",
       ]
     }
     deps += [
diff --git a/chrome/browser/ash/crosapi/network_settings_service_ash.cc b/chrome/browser/ash/crosapi/network_settings_service_ash.cc
index a1b4e8e..9449e8c 100644
--- a/chrome/browser/ash/crosapi/network_settings_service_ash.cc
+++ b/chrome/browser/ash/crosapi/network_settings_service_ash.cc
@@ -121,15 +121,15 @@
 
   // Required to display the extension which is controlling the proxy in the OS
   // Settings > Network > Proxy window.
-  base::Value proxy_extension(base::Value::Type::DICT);
-  proxy_extension.SetStringKey(kPrefExtensionNameKey,
-                               proxy_config->extension->name);
-  proxy_extension.SetStringKey(kPrefExtensionIdKey,
-                               proxy_config->extension->id);
-  proxy_extension.SetBoolKey(kPrefExtensionCanDisabledKey,
-                             proxy_config->extension->can_be_disabled);
-  pref_service->Set(ash::prefs::kLacrosProxyControllingExtension,
-                    std::move(proxy_extension));
+  base::Value::Dict proxy_extension =
+      base::Value::Dict()
+          .Set(kPrefExtensionNameKey, proxy_config->extension->name)
+          .Set(kPrefExtensionIdKey, proxy_config->extension->id)
+          .Set(kPrefExtensionCanDisabledKey,
+               proxy_config->extension->can_be_disabled);
+
+  pref_service->SetDict(ash::prefs::kLacrosProxyControllingExtension,
+                        std::move(proxy_extension));
 
   pref_service->SetDict(proxy_config::prefs::kProxy,
                         CrosapiProxyToProxyConfig(std::move(proxy_config))
diff --git a/chrome/browser/ash/crosapi/network_settings_service_ash_browsertest.cc b/chrome/browser/ash/crosapi/network_settings_service_ash_browsertest.cc
index 59e079e..5a6efbc 100644
--- a/chrome/browser/ash/crosapi/network_settings_service_ash_browsertest.cc
+++ b/chrome/browser/ash/crosapi/network_settings_service_ash_browsertest.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/ash/crosapi/network_settings_service_ash.h"
 
 #include "ash/constants/ash_pref_names.h"
-#include "base/functional/callback.h"
 #include "base/test/repeating_test_future.h"
 #include "chrome/browser/ash/crosapi/network_settings_translation.h"
 #include "chrome/browser/browser_process.h"
@@ -13,10 +12,8 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/testing_browser_process.h"
-#include "chromeos/ash/components/dbus/dbus_thread_manager.h"
 #include "chromeos/ash/components/dbus/shill/shill_profile_client.h"
 #include "chromeos/ash/components/dbus/shill/shill_service_client.h"
-#include "chromeos/ash/components/network/network_state.h"
 #include "chromeos/ash/components/network/network_state_handler.h"
 #include "chromeos/crosapi/mojom/network_settings_service.mojom.h"
 #include "components/policy/core/browser/browser_policy_connector.h"
@@ -30,9 +27,7 @@
 #include "components/proxy_config/proxy_config_pref_names.h"
 #include "components/proxy_config/proxy_prefs.h"
 #include "content/public/test/browser_test.h"
-#include "net/base/proxy_server.h"
 #include "third_party/cros_system_api/dbus/shill/dbus-constants.h"
-#include "url/url_constants.h"
 
 namespace {
 
@@ -208,18 +203,21 @@
     ProxyConfigDictionary proxy_config_dict(std::move(proxy_dict));
     auto proxy_config =
         crosapi::ProxyConfigToCrosapiProxy(&proxy_config_dict,
-                                           /*wpad_url=*/GURL(""));
+                                           /*dhcp_wpad_url=*/GURL(""));
     proxy_config->extension = crosapi::mojom::ExtensionControllingProxy::New();
     proxy_config->extension->name = kExtensionName;
     proxy_config->extension->id = kExtensionId;
     proxy_config->extension->can_be_disabled = can_be_disabled;
     network_service_ash_->SetExtensionProxy(std::move(proxy_config));
 
-    base::Value expected_pref(base::Value::Type::DICT);
-    expected_pref.SetStringKey(kPrefExtensionNameKey, kExtensionName);
-    expected_pref.SetStringKey(kPrefExtensionIdKey, kExtensionId);
-    expected_pref.SetBoolKey(kPrefExtensionCanDisabled, can_be_disabled);
-    WaitForLacrosProxyControllingExtensionPref(std::move(expected_pref));
+    base::Value::Dict expected_pref =
+        base::Value::Dict()
+            .Set(kPrefExtensionNameKey, kExtensionName)
+            .Set(kPrefExtensionIdKey, kExtensionId)
+            .Set(kPrefExtensionCanDisabled, can_be_disabled);
+
+    WaitForLacrosProxyControllingExtensionPref(
+        base::Value(std::move(expected_pref)));
   }
 
   void WaitForLacrosProxyControllingExtensionPref(
@@ -270,8 +268,7 @@
   result = observer_->WaitForProxyConfig();
   ASSERT_FALSE(result.is_null());
   EXPECT_TRUE(result->extension.is_null());
-  EXPECT_EQ(*(extension_proxy_pref->GetValue()),
-            base::Value(base::Value::Type::DICT));
+  EXPECT_EQ(*(extension_proxy_pref->GetValue()), base::Value::Dict());
   // proxy_mode=system is the default value (see
   // PrefProxyConfigTrackerImpl::RegisterProfilePrefs).
   EXPECT_EQ(*(proxy_pref->GetValue()), ProxyConfigDictionary::CreateSystem());
@@ -330,8 +327,8 @@
   ProxyConfigDictionary proxy_config_dict(
       ProxyConfigDictionary::CreatePacScript(kPacUrl,
                                              /*pac_mandatory=*/true));
-  auto proxy_config = crosapi::ProxyConfigToCrosapiProxy(&proxy_config_dict,
-                                                         /*wpad_url=*/GURL(""));
+  auto proxy_config = crosapi::ProxyConfigToCrosapiProxy(
+      &proxy_config_dict, /*dhcp_wpad_url=*/GURL(""));
   proxy_config->extension = crosapi::mojom::ExtensionControllingProxy::New();
   proxy_config->extension->name = kExtensionName;
   proxy_config->extension->id = kExtensionId;
diff --git a/chrome/browser/ash/login/chrome_restart_request.cc b/chrome/browser/ash/login/chrome_restart_request.cc
index 5f472dd7..bba2b919 100644
--- a/chrome/browser/ash/login/chrome_restart_request.cc
+++ b/chrome/browser/ash/login/chrome_restart_request.cc
@@ -185,7 +185,6 @@
     blink::switches::kEnableRasterSideDarkModeForImages,
     blink::switches::kEnableZeroCopy,
     blink::switches::kGpuRasterizationMSAASampleCount,
-    blink::switches::kNumRasterThreads,
     switches::kAshPowerButtonPosition,
     switches::kAshSideVolumeButtonPosition,
     switches::kDefaultWallpaperLarge,
@@ -202,6 +201,7 @@
     cc::switches::kEnableGpuBenchmarking,
     cc::switches::kEnableMainFrameBeforeActivation,
     cc::switches::kHighlightNonLCDTextLayers,
+    cc::switches::kNumRasterThreads,
     cc::switches::kShowCompositedLayerBorders,
     cc::switches::kShowFPSCounter,
     cc::switches::kShowLayerAnimationBounds,
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/BUILD.gn b/chrome/browser/ash/login/oobe_quick_start/connectivity/BUILD.gn
index 773d3bf..2efae0bb 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/BUILD.gn
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/BUILD.gn
@@ -30,8 +30,6 @@
     "fast_pair_advertiser.h",
     "fido_assertion_info.cc",
     "fido_assertion_info.h",
-    "incoming_connection.cc",
-    "incoming_connection.h",
     "random_session_id.cc",
     "random_session_id.h",
     "target_device_connection_broker.cc",
@@ -85,7 +83,6 @@
     "authenticated_connection_unittest.cc",
     "connection_unittest.cc",
     "fast_pair_advertiser_unittest.cc",
-    "incoming_connection_unittest.cc",
     "target_device_connection_broker_impl_unittest.cc",
   ]
 }
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/authenticated_connection.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/authenticated_connection.cc
index d69eb5f6..9960f0f 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/authenticated_connection.cc
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/authenticated_connection.cc
@@ -69,7 +69,8 @@
     int32_t session_id,
     RequestWifiCredentialsCallback callback) {
   // Build the Wifi Credential Request payload
-  std::string shared_secret_str(shared_secret_.begin(), shared_secret_.end());
+  std::string shared_secret_str(secondary_shared_secret_.begin(),
+                                secondary_shared_secret_.end());
   SendMessage(
       requests::BuildRequestWifiCredentialsMessage(session_id,
                                                    shared_secret_str),
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/authenticated_connection_unittest.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/authenticated_connection_unittest.cc
index 3a6539c..2584266 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/authenticated_connection_unittest.cc
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/authenticated_connection_unittest.cc
@@ -139,11 +139,9 @@
   EXPECT_TRUE(wifi_request_payload.FindBool("request_wifi"));
   EXPECT_EQ(wifi_request_payload.FindInt("SESSION_ID"), session_id);
 
-  std::string shared_secret_str(kSharedSecret.begin(), kSharedSecret.end());
-  std::string shared_secret_base64;
-  base::Base64Encode(shared_secret_str, &shared_secret_base64);
-  EXPECT_EQ(*wifi_request_payload.FindString("shared_secret"),
-            shared_secret_base64);
+  // TODO(b/234655072): Create kSecondarySharedSecret const and check value
+  // equals after AuthenticatedConnection refactor is merged.
+  EXPECT_TRUE(wifi_request_payload.FindString("shared_secret"));
 }
 
 TEST_F(AuthenticatedConnectionTest, RequestAccountTransferAssertion) {
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.cc
index ba0bc9a5..c9f7c80 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.cc
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.cc
@@ -17,12 +17,15 @@
                        SharedSecret shared_secret)
     : nearby_connection_(nearby_connection),
       random_session_id_(session_id),
-      shared_secret_(shared_secret) {}
+      shared_secret_(shared_secret) {
+  crypto::RandBytes(secondary_shared_secret_);
+}
 
 Connection::Connection(NearbyConnection* nearby_connection,
                        RandomSessionId session_id)
     : nearby_connection_(nearby_connection), random_session_id_(session_id) {
   crypto::RandBytes(shared_secret_);
+  crypto::RandBytes(secondary_shared_secret_);
 }
 
 void Connection::SendPayload(const base::Value::Dict& message_payload) {
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.h b/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.h
index 66be7a0..8ac8311e 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.h
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.h
@@ -43,6 +43,7 @@
   NearbyConnection* nearby_connection_;
   RandomSessionId random_session_id_;
   SharedSecret shared_secret_;
+  SharedSecret secondary_shared_secret_;
 };
 
 }  // namespace ash::quick_start
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_target_device_connection_broker.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_target_device_connection_broker.cc
index c88dd18..c89095de 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_target_device_connection_broker.cc
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_target_device_connection_broker.cc
@@ -16,15 +16,15 @@
 
 namespace {
 
-// Arbitrary string to use as the connection's authentication token.
-constexpr char kAuthenticationToken[] = "auth_token";
-
 // 32 random bytes to use as the shared secret.
 constexpr std::array<uint8_t, 32> kSharedSecret = {
     0x54, 0xbd, 0x40, 0xcf, 0x8a, 0x7c, 0x2f, 0x6a, 0xca, 0x15, 0x59,
     0xcf, 0xf3, 0xeb, 0x31, 0x08, 0x90, 0x73, 0xef, 0xda, 0x87, 0xd4,
     0x23, 0xc0, 0x55, 0xd5, 0x83, 0x5b, 0x04, 0x28, 0x49, 0xf2};
 
+// Arbitrary string to use as the connection's authentication token when
+// deriving PIN.
+constexpr char kAuthenticationToken[] = "auth_token";
 }  // namespace
 
 FakeTargetDeviceConnectionBroker::Factory::Factory() = default;
@@ -52,6 +52,7 @@
 
 void FakeTargetDeviceConnectionBroker::StartAdvertising(
     ConnectionLifecycleListener* listener,
+    bool use_pin_authentication,
     ResultCallback on_start_advertising_callback) {
   ++num_start_advertising_calls_;
   connection_lifecycle_listener_ = listener;
@@ -66,15 +67,14 @@
 
 void FakeTargetDeviceConnectionBroker::InitiateConnection(
     const std::string& source_device_id) {
-  auto random_session_id = RandomSessionId();
-  fake_nearby_connection_ = std::make_unique<FakeNearbyConnection>();
-  NearbyConnection* nearby_connection = fake_nearby_connection_.get();
-  fake_quick_start_decoder_ = std::make_unique<FakeQuickStartDecoder>();
-  auto fake_incomming_connection = std::make_unique<FakeIncommingConnection>(
-      nearby_connection, random_session_id, kAuthenticationToken);
-  connection_lifecycle_listener_->OnIncomingConnectionInitiated(
-      source_device_id, fake_incomming_connection->AsWeakPtr());
-  fake_connection_ = std::move(fake_incomming_connection);
+  if (use_pin_authentication_) {
+    connection_lifecycle_listener_->OnPinVerificationRequested(
+        DerivePin(kAuthenticationToken));
+  } else {
+    auto random_session_id = RandomSessionId();
+    connection_lifecycle_listener_->OnQRCodeVerificationRequested(
+        GetQrCodeData(random_session_id, kSharedSecret));
+  }
 }
 
 void FakeTargetDeviceConnectionBroker::AuthenticateConnection(
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_target_device_connection_broker.h b/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_target_device_connection_broker.h
index 4a945a90..f6c347e1d 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_target_device_connection_broker.h
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/fake_target_device_connection_broker.h
@@ -9,14 +9,14 @@
 #include <vector>
 
 #include "chrome/browser/ash/login/oobe_quick_start/connectivity/authenticated_connection.h"
-#include "chrome/browser/ash/login/oobe_quick_start/connectivity/fake_quick_start_decoder.h"
-#include "chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.h"
 #include "chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.h"
 #include "chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_factory.h"
-#include "chrome/browser/nearby_sharing/fake_nearby_connection.h"
+
+class FakeNearbyConnection;
 
 namespace ash::quick_start {
 
+class FakeQuickStartDecoder;
 class RandomSessionId;
 
 class FakeTargetDeviceConnectionBroker : public TargetDeviceConnectionBroker {
@@ -49,13 +49,6 @@
     std::vector<FakeTargetDeviceConnectionBroker*> instances_;
   };
 
-  class FakeIncommingConnection
-      : public IncomingConnection,
-        public base::SupportsWeakPtr<FakeIncommingConnection> {
-   public:
-    using IncomingConnection::IncomingConnection;
-  };
-
   class FakeAuthenticatedConnection
       : public AuthenticatedConnection,
         public base::SupportsWeakPtr<FakeAuthenticatedConnection> {
@@ -72,6 +65,7 @@
   // TargetDeviceConnectionBroker:
   FeatureSupportStatus GetFeatureSupportStatus() const override;
   void StartAdvertising(ConnectionLifecycleListener* listener,
+                        bool use_pin_authentication,
                         ResultCallback on_start_advertising_callback) override;
   void StopAdvertising(base::OnceClosure on_stop_advertising_callback) override;
   void InitiateConnection(const std::string& source_device_id);
@@ -84,6 +78,10 @@
     MaybeNotifyFeatureStatus();
   }
 
+  void set_use_pin_authentication(bool use_pin_authentication) {
+    use_pin_authentication_ = use_pin_authentication;
+  }
+
   size_t num_start_advertising_calls() const {
     return num_start_advertising_calls_;
   }
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.cc
deleted file mode 100644
index 0538e87..0000000
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.cc
+++ /dev/null
@@ -1,60 +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/ash/login/oobe_quick_start/connectivity/incoming_connection.h"
-
-#include "base/base64url.h"
-#include "base/hash/sha1.h"
-#include "base/strings/string_number_conversions.h"
-#include "chrome/browser/ash/login/oobe_quick_start/connectivity/random_session_id.h"
-#include "crypto/random.h"
-
-namespace ash::quick_start {
-
-IncomingConnection::IncomingConnection(NearbyConnection* nearby_connection,
-                                       RandomSessionId session_id,
-                                       const std::string& authentication_token)
-    : Connection(nearby_connection, session_id),
-      pin_(DerivePin(authentication_token)) {}
-
-IncomingConnection::IncomingConnection(NearbyConnection* nearby_connection,
-                                       RandomSessionId session_id,
-                                       const std::string& authentication_token,
-                                       SharedSecret shared_secret)
-    : Connection(nearby_connection, session_id, shared_secret),
-      pin_(DerivePin(authentication_token)) {}
-
-IncomingConnection::~IncomingConnection() = default;
-
-std::string IncomingConnection::DerivePin(
-    const std::string& authentication_token) {
-  std::string hash_str = base::SHA1HashString(authentication_token);
-  std::vector<int8_t> hash_ints =
-      std::vector<int8_t>(hash_str.begin(), hash_str.end());
-
-  return base::NumberToString(
-             std::abs((hash_ints[0] << 8 | hash_ints[1]) % 10)) +
-         base::NumberToString(
-             std::abs((hash_ints[2] << 8 | hash_ints[3]) % 10)) +
-         base::NumberToString(
-             std::abs((hash_ints[4] << 8 | hash_ints[5]) % 10)) +
-         base::NumberToString(
-             std::abs((hash_ints[6] << 8 | hash_ints[7]) % 10));
-}
-
-std::vector<uint8_t> IncomingConnection::GetQrCodeData() const {
-  std::string shared_secret_str(shared_secret_.begin(), shared_secret_.end());
-  std::string shared_secret_base64;
-  base::Base64UrlEncode(shared_secret_str,
-                        base::Base64UrlEncodePolicy::OMIT_PADDING,
-                        &shared_secret_base64);
-
-  std::string url = "https://signin.google/qs/" +
-                    random_session_id_.ToString() +
-                    "?key=" + shared_secret_base64;
-
-  return std::vector<uint8_t>(url.begin(), url.end());
-}
-
-}  // namespace ash::quick_start
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.h b/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.h
deleted file mode 100644
index 1427ea7..0000000
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.h
+++ /dev/null
@@ -1,56 +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_ASH_LOGIN_OOBE_QUICK_START_CONNECTIVITY_INCOMING_CONNECTION_H_
-#define CHROME_BROWSER_ASH_LOGIN_OOBE_QUICK_START_CONNECTIVITY_INCOMING_CONNECTION_H_
-
-#include <array>
-
-#include "chrome/browser/ash/login/oobe_quick_start/connectivity/connection.h"
-#include "chrome/browser/ash/login/oobe_quick_start/connectivity/random_session_id.h"
-
-namespace ash::quick_start {
-
-// Represents a new incoming connection that has not yet been accepted by the
-// remote source device.
-class IncomingConnection : public Connection {
- public:
-  IncomingConnection(NearbyConnection* nearby_connection,
-                     RandomSessionId session_id,
-                     const std::string& authentication_token);
-
-  // An alternate constructor that accepts a shared_secret for testing purposes
-  // or for resuming a connection after a critical update.
-  IncomingConnection(NearbyConnection* nearby_connection,
-                     RandomSessionId session_id,
-                     const std::string& authentication_token,
-                     std::array<uint8_t, 32> shared_secret);
-
-  IncomingConnection(IncomingConnection&) = delete;
-  IncomingConnection& operator=(IncomingConnection&) = delete;
-  ~IncomingConnection() override;
-
-  // Derive a 4-digit decimal pin code from the authentication token. This is
-  // meant to match the Android implementation found here:
-  // http://google3/java/com/google/android/gmscore/integ/modules/smartdevice/src/com/google/android/gms/smartdevice/d2d/nearby/advertisement/VerificationUtils.java;l=37;rcl=511361463
-  static std::string DerivePin(const std::string& authentication_token);
-
-  // Returns a deep link URL as a vector of bytes that will form the QR code
-  // used to authenticate the connection.
-  std::vector<uint8_t> GetQrCodeData() const;
-
-  // Return the 4-digit pin code to be displayed for the user to match against
-  // the source device in order to authenticate the connection. Derived from the
-  // Nearby Connection's authentication token.
-  std::string GetConnectionVerificationPin() const { return pin_; }
-
- private:
-  // A 4-digit decimal pin code derived from the connection's authentication
-  // token for the alternative pin authentication flow.
-  std::string pin_;
-};
-
-}  // namespace ash::quick_start
-
-#endif  // CHROME_BROWSER_ASH_LOGIN_OOBE_QUICK_START_CONNECTIVITY_INCOMING_CONNECTION_H_
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection_unittest.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection_unittest.cc
deleted file mode 100644
index 3743fa5..0000000
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection_unittest.cc
+++ /dev/null
@@ -1,95 +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/ash/login/oobe_quick_start/connectivity/incoming_connection.h"
-
-#include <memory>
-
-#include "chrome/browser/ash/login/oobe_quick_start/connectivity/random_session_id.h"
-#include "chrome/browser/nearby_sharing/fake_nearby_connection.h"
-#include "chrome/browser/nearby_sharing/public/cpp/nearby_connection.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace ash::quick_start {
-
-namespace {
-
-// Base qr code url ("https://signin.google/qs/") represented in a 25 byte
-// array.
-constexpr std::array<uint8_t, 25> kBaseUrl = {
-    0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x73,
-    0x69, 0x67, 0x6e, 0x69, 0x6e, 0x2e, 0x67, 0x6f, 0x6f,
-    0x67, 0x6c, 0x65, 0x2f, 0x71, 0x73, 0x2f};
-
-// Qr code key param ("?key=") represented in a 5 byte array.
-constexpr std::array<uint8_t, 5> kUrlKeyParam = {0x3f, 0x6b, 0x65, 0x79, 0x3d};
-
-// 6 random bytes to use as the RandomSessionId.
-constexpr std::array<uint8_t, 6> kRandomSessionId = {0x6b, 0xb3, 0x85,
-                                                     0x27, 0xbb, 0x28};
-
-// Base64 representation of kRandomSessionId.
-constexpr char kRandomSessionIdBase64[] = "a7OFJ7so";
-
-// 32 random bytes to use as the shared secret.
-constexpr std::array<uint8_t, 32> kSharedSecret = {
-    0x54, 0xbd, 0x40, 0xcf, 0x8a, 0x7c, 0x2f, 0x6a, 0xca, 0x15, 0x59,
-    0xcf, 0xf3, 0xeb, 0x31, 0x08, 0x90, 0x73, 0xef, 0xda, 0x87, 0xd4,
-    0x23, 0xc0, 0x55, 0xd5, 0x83, 0x5b, 0x04, 0x28, 0x49, 0xf2};
-
-// Base64 representation of kSharedSecret.
-constexpr char kSharedSecretBase64[] =
-    "VL1Az4p8L2rKFVnP8-sxCJBz79qH1CPAVdWDWwQoSfI";
-
-// Arbitrary string to use as the connection's authentication token.
-constexpr char kAuthenticationToken[] = "auth_token";
-
-// Pin corresponding to |kAuthenticationToken|.
-constexpr char kAuthenticationTokenPin[] = "6229";
-
-}  // namespace
-
-class IncomingConnectionTest : public testing::Test {
- public:
-  IncomingConnectionTest(const IncomingConnectionTest&) = delete;
-  IncomingConnectionTest& operator=(const IncomingConnectionTest&) = delete;
-
- protected:
-  IncomingConnectionTest() = default;
-
-  void SetUp() override {
-    RandomSessionId session_id(kRandomSessionId);
-    fake_nearby_connection_ = std::make_unique<FakeNearbyConnection>();
-    NearbyConnection* nearby_connection = fake_nearby_connection_.get();
-    incoming_connection_ = std::make_unique<IncomingConnection>(
-        nearby_connection, session_id, kAuthenticationToken, kSharedSecret);
-  }
-
-  std::unique_ptr<IncomingConnection> incoming_connection_;
-  std::unique_ptr<FakeNearbyConnection> fake_nearby_connection_;
-};
-
-TEST_F(IncomingConnectionTest, TestGetQrCodeData) {
-  std::string session_id(kRandomSessionIdBase64);
-  std::string shared_secret(kSharedSecretBase64);
-
-  std::vector<uint8_t> expected_data(std::begin(kBaseUrl), std::end(kBaseUrl));
-  expected_data.insert(expected_data.end(), session_id.begin(),
-                       session_id.end());
-  expected_data.insert(expected_data.end(), std::begin(kUrlKeyParam),
-                       std::end(kUrlKeyParam));
-  expected_data.insert(expected_data.end(), shared_secret.begin(),
-                       shared_secret.end());
-
-  std::vector<uint8_t> actual_data = incoming_connection_->GetQrCodeData();
-
-  EXPECT_EQ(expected_data, actual_data);
-}
-
-TEST_F(IncomingConnectionTest, GetConnectionVerificationPin) {
-  EXPECT_EQ(kAuthenticationTokenPin,
-            incoming_connection_->GetConnectionVerificationPin());
-}
-
-}  // namespace ash::quick_start
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.cc
index 70efd57..64229175 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.cc
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.cc
@@ -4,9 +4,11 @@
 
 #include "chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.h"
 
-namespace ash::quick_start {
+#include "base/base64url.h"
+#include "base/hash/sha1.h"
+#include "base/strings/string_number_conversions.h"
 
-// TODO impl
+namespace ash::quick_start {
 
 TargetDeviceConnectionBroker::TargetDeviceConnectionBroker() = default;
 TargetDeviceConnectionBroker::~TargetDeviceConnectionBroker() = default;
@@ -29,4 +31,34 @@
   }
 }
 
+std::vector<uint8_t> TargetDeviceConnectionBroker::GetQrCodeData(
+    const RandomSessionId& random_session_id,
+    const Connection::SharedSecret shared_secret) const {
+  std::string shared_secret_str(shared_secret.begin(), shared_secret.end());
+  std::string shared_secret_base64;
+  base::Base64UrlEncode(shared_secret_str,
+                        base::Base64UrlEncodePolicy::OMIT_PADDING,
+                        &shared_secret_base64);
+
+  std::string url = "https://signin.google/qs/" + random_session_id.ToString() +
+                    "?key=" + shared_secret_base64;
+
+  return std::vector<uint8_t>(url.begin(), url.end());
+}
+
+std::string TargetDeviceConnectionBroker::DerivePin(
+    const std::string& authentication_token) const {
+  std::string hash_str = base::SHA1HashString(authentication_token);
+  std::vector<int8_t> hash_ints =
+      std::vector<int8_t>(hash_str.begin(), hash_str.end());
+  return base::NumberToString(
+             std::abs((hash_ints[0] << 8 | hash_ints[1]) % 10)) +
+         base::NumberToString(
+             std::abs((hash_ints[2] << 8 | hash_ints[3]) % 10)) +
+         base::NumberToString(
+             std::abs((hash_ints[4] << 8 | hash_ints[5]) % 10)) +
+         base::NumberToString(
+             std::abs((hash_ints[6] << 8 | hash_ints[7]) % 10));
+}
+
 }  // namespace ash::quick_start
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.h b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.h
index 0ea3c05..d6d576d 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.h
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.h
@@ -9,11 +9,12 @@
 
 #include "base/functional/callback.h"
 #include "base/memory/weak_ptr.h"
+#include "chrome/browser/ash/login/oobe_quick_start/connectivity/connection.h"
+#include "chrome/browser/ash/login/oobe_quick_start/connectivity/random_session_id.h"
 
 namespace ash::quick_start {
 
 class AuthenticatedConnection;
-class IncomingConnection;
 
 // TargetDeviceConnectionBroker is the entrypoint for consuming the Quick Start
 // connectivity component. Calling code is expected to get an instance of this
@@ -45,24 +46,21 @@
     ConnectionLifecycleListener() = default;
     virtual ~ConnectionLifecycleListener() = default;
 
-    // A basic encrypted channel has been created between this target device and
-    // the remote source device. The connection has been blindly accepted by
-    // this target device, but it is the responsibility of the source device to
-    // make an informed choice to accept. The user of the source device makes
-    // this decision by inspecting the UI of this target device, which is
-    // expected to display the metadata that the IncomingConnection object
-    // provides (QR Code or shapes/PIN matching).
-    //
-    // The IncomingConnection pointer may be cached, but will become invalid
-    // after either OnConnectionAuthenticated(), OnConnectionRejected(), or
-    // OnConnectionClosed() are called.
-    //
-    // Use source_device_id to understand which connection
-    // OnConnectionAuthenticated(), OnConnectionRejected(), or
-    // OnConnectionClosed() refers to.
-    virtual void OnIncomingConnectionInitiated(
-        const std::string& source_device_id,
-        base::WeakPtr<IncomingConnection> connection) = 0;
+    // A connection has been initiated between this target device and the remote
+    // source device, but needs to be authenticated before messages can be
+    // exchanged. The source device has requested that the pin be displayed so
+    // that the user can check that the codes match, thereby authenticating the
+    // connection.
+    virtual void OnPinVerificationRequested(const std::string& pin) = 0;
+
+    // A connection has been initiated between this target device and the remote
+    // source device, but needs to be authenticated before messages can be
+    // exchanged. The source device has requested that the QR code be displayed
+    // so that the user can scan the code. After scanning, the source device
+    // will accept the connection, and a cryptographic handshake using a secret
+    // contained in the QR code will be used to authenticate the connection.
+    virtual void OnQRCodeVerificationRequested(
+        const std::vector<uint8_t>& qr_code_data) = 0;
 
     // Called after both sides have accepted the connection.
     //
@@ -101,15 +99,22 @@
   // Will kick off Fast Pair and Nearby Connections advertising.
   // Clients can use the result of |on_start_advertising_callback| to
   // immediately understand if advertising succeeded, and can then wait for the
-  // source device to connect via
-  // |ConnectionLifecycleListener::OnIncomingConnectionInitiated()|.
+  // source device to connect and request authentication via
+  // |ConnectionLifecycleListener::OnPinVerificationRequested()| or
+  // |ConnectionLifecycleListener::OnQRCodeVerificationRequested()|.
   //
   // If the caller paused a connection previously, the connection to the
   // source device will resume via OnConnectionAuthenticated().
   // Clients should check  GetFeatureSupportStatus()  before calling
   // StartAdvertising().
+  //
+  // If |use_pin_authentication| is true, then the target device will
+  // advertise its preference to use pin authentication instead of QR code
+  // authentication. This should be false unless the user would benefit from
+  // using pin for, e.g. accessibility reasons.
   virtual void StartAdvertising(
       ConnectionLifecycleListener* listener,
+      bool use_pin_authentication,
       ResultCallback on_start_advertising_callback) = 0;
 
   // Clients are responsible for calling this once they have accepted their
@@ -120,6 +125,21 @@
  protected:
   void MaybeNotifyFeatureStatus();
 
+  // Returns a deep link URL as a vector of bytes that will form the QR code
+  // used to authenticate the connection.
+  std::vector<uint8_t> GetQrCodeData(
+      const RandomSessionId& random_session_id,
+      const Connection::SharedSecret shared_secret) const;
+
+  // Derive a 4-digit decimal pin code from the authentication token. This is
+  // meant to match the Android implementation found here:
+  // http://google3/java/com/google/android/gmscore/integ/modules/smartdevice/src/com/google/android/gms/smartdevice/d2d/nearby/advertisement/VerificationUtils.java;l=37;rcl=511361463
+  std::string DerivePin(const std::string& authentication_token) const;
+
+  // Determines whether the advertisement info sent to the source device will
+  // request pin verification or QR code verification.
+  bool use_pin_authentication_ = false;
+
  private:
   std::vector<FeatureSupportStatusCallback> feature_status_callbacks_;
 };
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl.cc
index 433989f..28c8d8a 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl.cc
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl.cc
@@ -11,14 +11,13 @@
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
 #include "base/logging.h"
-#include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/task/sequenced_task_runner.h"
 #include "chrome/browser/ash/login/oobe_quick_start/connectivity/fast_pair_advertiser.h"
-#include "chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.h"
 #include "chrome/browser/ash/login/oobe_quick_start/connectivity/random_session_id.h"
 #include "chrome/browser/ash/login/oobe_quick_start/logging/logging.h"
+#include "crypto/random.h"
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_adapter_factory.h"
 #include "ui/chromeos/devicetype_utils.h"
@@ -31,10 +30,12 @@
 constexpr uint8_t kEndpointInfoVersion = 1;
 
 // Smart Setup verification style, e.g. QR code, pin, etc.
-// 6 = "DIGITS", which tells the phone to display a code for the user to match.
+// 5 = "OUT_OF_BAND", which tells the phone to scan for the QR code.
+// 6 = "DIGITS", which tells the phone to display a PIN for the user to match.//
 // Values come from the TargetConnectionInfo VerificationStyle enum:
-constexpr uint8_t kEndpointInfoVerificationStyle = 6;
-
+// http://google3/logs/proto/wireless/android/smartsetup/smart_setup_extension.proto;l=894;rcl=489739066
+constexpr uint8_t kEndpointInfoVerificationStyleOutOfBand = 5;
+constexpr uint8_t kEndpointInfoVerificationStyleDigits = 6;
 // Device Type for Smart Setup, e.g. phone, tablet.  8 = "Chrome"
 // Values come from the DiscoveryEvent DeviceType enum:
 // http://google3/logs/proto/wireless/android/smartsetup/smart_setup_extension.proto;l=985;rcl=507029311
@@ -124,6 +125,7 @@
     base::WeakPtr<NearbyConnectionsManager> nearby_connections_manager)
     : random_session_id_(session_id),
       nearby_connections_manager_(nearby_connections_manager) {
+  crypto::RandBytes(shared_secret_);
   GetBluetoothAdapter();
 }
 
@@ -167,14 +169,13 @@
 
 void TargetDeviceConnectionBrokerImpl::StartAdvertising(
     ConnectionLifecycleListener* listener,
+    bool use_pin_authentication,
     ResultCallback on_start_advertising_callback) {
-  // TODO(b/234655072): Notify client about incoming connections on the started
-  // advertisement via ConnectionLifecycleListener.
   if (GetFeatureSupportStatus() == FeatureSupportStatus::kUndetermined) {
-    deferred_start_advertising_callback_ =
-        base::BindOnce(&TargetDeviceConnectionBroker::StartAdvertising,
-                       weak_ptr_factory_.GetWeakPtr(), listener,
-                       std::move(on_start_advertising_callback));
+    deferred_start_advertising_callback_ = base::BindOnce(
+        &TargetDeviceConnectionBroker::StartAdvertising,
+        weak_ptr_factory_.GetWeakPtr(), listener, use_pin_authentication,
+        std::move(on_start_advertising_callback));
     return;
   }
 
@@ -196,6 +197,9 @@
     return;
   }
 
+  use_pin_authentication_ = use_pin_authentication;
+  connection_lifecycle_listener_ = listener;
+
   // This will start Nearby Connections advertising if Fast Pair advertising
   // succeeds.
   StartFastPairAdvertising(std::move(on_start_advertising_callback));
@@ -269,14 +273,18 @@
 //   - isQuickStart, byte[12], =1 for Quick Start.
 //   - preferTargetUserVerification, byte[13], =0 for ChromeOS.
 //   - Pad with zeros to 60 bytes. Extra space reserved for futureproofing.
-std::vector<uint8_t> TargetDeviceConnectionBrokerImpl::GenerateEndpointInfo() {
+std::vector<uint8_t> TargetDeviceConnectionBrokerImpl::GenerateEndpointInfo()
+    const {
   std::string session_id = random_session_id_.ToString();
   std::vector<uint8_t> display_name_bytes =
       GetEndpointInfoDisplayNameBytes(random_session_id_);
+  uint8_t verification_style = use_pin_authentication_
+                                   ? kEndpointInfoVerificationStyleDigits
+                                   : kEndpointInfoVerificationStyleOutOfBand;
 
   std::vector<uint8_t> advertisement_data;
   advertisement_data.reserve(60);
-  advertisement_data.push_back(kEndpointInfoVerificationStyle);
+  advertisement_data.push_back(verification_style);
   advertisement_data.push_back(kEndpointInfoDeviceType);
   advertisement_data.insert(advertisement_data.end(), session_id.begin(),
                             session_id.end());
@@ -368,33 +376,38 @@
 void TargetDeviceConnectionBrokerImpl::OnIncomingConnectionInitiated(
     const std::string& endpoint_id,
     const std::vector<uint8_t>& endpoint_info) {
-  absl::optional<std::string> auth_token =
-      nearby_connections_manager_->GetAuthenticationToken(endpoint_id);
-  DCHECK(auth_token);
-  std::string pin = IncomingConnection::DerivePin(*auth_token);
   QS_LOG(INFO) << "Incoming Nearby Connection Initiated: endpoint_id="
-               << endpoint_id << " pin=" << pin;
+               << endpoint_id
+               << " use_pin_authentication=" << use_pin_authentication_;
 
-  // TODO(b/234655072): Notify ConnectionLifecycleListener about the incoming
-  // connection if pin authentication is expected.
+  CHECK(connection_lifecycle_listener_);
+  if (use_pin_authentication_) {
+    absl::optional<std::string> auth_token =
+        nearby_connections_manager_->GetAuthenticationToken(endpoint_id);
+    CHECK(auth_token);
+    std::string pin = DerivePin(*auth_token);
+    QS_LOG(INFO) << "Incoming Nearby Connection Initiated: pin=" << pin;
+    connection_lifecycle_listener_->OnPinVerificationRequested(pin);
+  } else {
+    connection_lifecycle_listener_->OnQRCodeVerificationRequested(
+        GetQrCodeData(random_session_id_, shared_secret_));
+  }
 }
 
 void TargetDeviceConnectionBrokerImpl::OnIncomingConnectionAccepted(
     const std::string& endpoint_id,
     const std::vector<uint8_t>& endpoint_info,
-    NearbyConnection* connection) {
-  absl::optional<std::string> auth_token =
-      nearby_connections_manager_->GetAuthenticationToken(endpoint_id);
-  DCHECK(auth_token);
-  std::unique_ptr<IncomingConnection> incoming_connection =
-      std::make_unique<IncomingConnection>(connection, random_session_id_,
-                                           *auth_token);
+    NearbyConnection* nearby_connection) {
   QS_LOG(INFO) << "Incoming Nearby Connection Accepted: endpoint_id="
-               << endpoint_id << " pin="
-               << incoming_connection->GetConnectionVerificationPin();
+               << endpoint_id;
 
-  // TODO(b/234655072): Notify ConnectionLifecycleListener about the incoming
-  // connection so that the Quick Start flow can proceed.
+  connection_ = std::make_unique<Connection>(
+      nearby_connection, random_session_id_, shared_secret_);
+
+  // TODO(b/234655072): Mark the connection_ authenticated if
+  // |use_pin_authentication_| is true. For pin verification, if the source
+  // device has accepted the Nearby Connection, then the connection is
+  // authenticated.
 }
 
 }  // namespace ash::quick_start
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl.h b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl.h
index 20abdc58..8b6f9c91 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl.h
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_ASH_LOGIN_OOBE_QUICK_START_CONNECTIVITY_TARGET_DEVICE_CONNECTION_BROKER_IMPL_H_
 
 #include "base/memory/weak_ptr.h"
+#include "chrome/browser/ash/login/oobe_quick_start/connectivity/connection.h"
 #include "chrome/browser/ash/login/oobe_quick_start/connectivity/random_session_id.h"
 #include "chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.h"
 #include "chrome/browser/nearby_sharing/public/cpp/nearby_connections_manager.h"
@@ -53,6 +54,7 @@
   // TargetDeviceConnectionBroker:
   FeatureSupportStatus GetFeatureSupportStatus() const override;
   void StartAdvertising(ConnectionLifecycleListener* listener,
+                        bool use_pin_authentication,
                         ResultCallback on_start_advertising_callback) override;
   void StopAdvertising(base::OnceClosure on_stop_advertising_callback) override;
 
@@ -65,9 +67,10 @@
   void OnIncomingConnectionInitiated(
       const std::string& endpoint_id,
       const std::vector<uint8_t>& endpoint_info) override;
-  void OnIncomingConnectionAccepted(const std::string& endpoint_id,
-                                    const std::vector<uint8_t>& endpoint_info,
-                                    NearbyConnection* connection) override;
+  void OnIncomingConnectionAccepted(
+      const std::string& endpoint_id,
+      const std::vector<uint8_t>& endpoint_info,
+      NearbyConnection* nearby_connection) override;
 
   void GetBluetoothAdapter();
   void OnGetBluetoothAdapter(scoped_refptr<device::BluetoothAdapter> adapter);
@@ -78,7 +81,7 @@
 
   // The EndpointInfo is the set of bytes that SmartSetup on Android expects to
   // be in the Nearby Connections advertisement.
-  std::vector<uint8_t> GenerateEndpointInfo();
+  std::vector<uint8_t> GenerateEndpointInfo() const;
 
   void StartNearbyConnectionsAdvertising(ResultCallback callback);
   void StopNearbyConnectionsAdvertising(base::OnceClosure callback);
@@ -89,11 +92,18 @@
       base::OnceClosure callback,
       NearbyConnectionsManager::ConnectionsStatus status);
 
+  // A 4-digit decimal pin code derived from the connection's authentication
+  // token for the pin authentication flow.
+  std::string pin_;
+
   scoped_refptr<device::BluetoothAdapter> bluetooth_adapter_;
   base::OnceClosure deferred_start_advertising_callback_;
 
   std::unique_ptr<FastPairAdvertiser> fast_pair_advertiser_;
   RandomSessionId random_session_id_;
+  Connection::SharedSecret shared_secret_;
+  ConnectionLifecycleListener* connection_lifecycle_listener_ = nullptr;
+  std::unique_ptr<Connection> connection_;
 
   base::WeakPtr<NearbyConnectionsManager> nearby_connections_manager_;
 
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl_unittest.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl_unittest.cc
index 956dcfc..48304ed6 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl_unittest.cc
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl_unittest.cc
@@ -28,7 +28,9 @@
 namespace {
 
 constexpr size_t kMaxEndpointInfoDisplayNameLength = 18;
-constexpr uint8_t kEndpointInfoVerificationStyle = 6u;
+// Default verification style 5 = "OUT_OF_BAND", which tells the phone to scan
+// for the QR code.
+constexpr uint8_t kEndpointInfoVerificationStyle = 5u;
 constexpr uint8_t kEndpointInfoDeviceType = 8u;
 
 constexpr size_t kEndpointInfoRandomSessionIdLength = 10;
@@ -38,6 +40,33 @@
 constexpr std::array<uint8_t, 6> kRandomSessionId = {0x13, 0x5e, 0xfb,
                                                      0x0f, 0x3a, 0x20};
 
+// Base qr code url ("https://signin.google/qs/") represented in a 25 byte
+// array.
+constexpr std::array<uint8_t, 25> kBaseUrl = {
+    0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x73,
+    0x69, 0x67, 0x6e, 0x69, 0x6e, 0x2e, 0x67, 0x6f, 0x6f,
+    0x67, 0x6c, 0x65, 0x2f, 0x71, 0x73, 0x2f};
+
+// Qr code key param ("?key=") represented in a 5 byte array.
+constexpr std::array<uint8_t, 5> kUrlKeyParam = {0x3f, 0x6b, 0x65, 0x79, 0x3d};
+
+// 32 random bytes to use as the shared secret when generating QR Code.
+constexpr std::array<uint8_t, 32> kSharedSecret = {
+    0x54, 0xbd, 0x40, 0xcf, 0x8a, 0x7c, 0x2f, 0x6a, 0xca, 0x15, 0x59,
+    0xcf, 0xf3, 0xeb, 0x31, 0x08, 0x90, 0x73, 0xef, 0xda, 0x87, 0xd4,
+    0x23, 0xc0, 0x55, 0xd5, 0x83, 0x5b, 0x04, 0x28, 0x49, 0xf2};
+
+// Base64 representation of kSharedSecret.
+constexpr char kSharedSecretBase64[] =
+    "VL1Az4p8L2rKFVnP8-sxCJBz79qH1CPAVdWDWwQoSfI";
+
+// Arbitrary string to use as the connection's authentication token when
+// deriving PIN.
+constexpr char kAuthenticationToken[] = "auth_token";
+
+// Expected PIN corresponding to |kAuthenticationToken|.
+constexpr char kAuthenticationTokenPin[] = "6229";
+
 // Perform base64 decoding with the kForgiving option to allow for missing
 // padding.
 std::vector<uint8_t> Base64DecodeForgiving(base::span<uint8_t> input) {
@@ -282,6 +311,19 @@
         ->random_session_id_;
   }
 
+  const std::vector<uint8_t> GetQrCodeData() {
+    const RandomSessionId& session_id = GetRandomSessionId();
+    return static_cast<TargetDeviceConnectionBrokerImpl*>(
+               connection_broker_.get())
+        ->GetQrCodeData(session_id, kSharedSecret);
+  }
+
+  std::string DerivePin() {
+    return static_cast<TargetDeviceConnectionBrokerImpl*>(
+               connection_broker_.get())
+        ->DerivePin(kAuthenticationToken);
+  }
+
  protected:
   bool is_bluetooth_powered_ = true;
   bool is_bluetooth_present_ = true;
@@ -330,7 +372,7 @@
   EXPECT_EQ(0u, fast_pair_advertiser_factory_->StartAdvertisingCount());
 
   connection_broker_->StartAdvertising(
-      nullptr,
+      nullptr, /* use_pin_authentication= */ false,
       base::BindOnce(
           &TargetDeviceConnectionBrokerImplTest::StartAdvertisingResultCallback,
           weak_ptr_factory_.GetWeakPtr()));
@@ -344,7 +386,7 @@
   EXPECT_EQ(0u, fast_pair_advertiser_factory_->StartAdvertisingCount());
 
   connection_broker_->StartAdvertising(
-      nullptr,
+      nullptr, /* use_pin_authentication= */ false,
       base::BindOnce(
           &TargetDeviceConnectionBrokerImplTest::StartAdvertisingResultCallback,
           weak_ptr_factory_.GetWeakPtr()));
@@ -364,7 +406,7 @@
   EXPECT_EQ(0u, fast_pair_advertiser_factory_->StartAdvertisingCount());
 
   connection_broker_->StartAdvertising(
-      nullptr,
+      nullptr, /* use_pin_authentication= */ false,
       base::BindOnce(
           &TargetDeviceConnectionBrokerImplTest::StartAdvertisingResultCallback,
           weak_ptr_factory_.GetWeakPtr()));
@@ -380,7 +422,7 @@
   EXPECT_EQ(0u, fast_pair_advertiser_factory_->StartAdvertisingCount());
 
   connection_broker_->StartAdvertising(
-      nullptr,
+      nullptr, /* use_pin_authentication= */ false,
       base::BindOnce(
           &TargetDeviceConnectionBrokerImplTest::StartAdvertisingResultCallback,
           weak_ptr_factory_.GetWeakPtr()));
@@ -396,7 +438,7 @@
   EXPECT_EQ(0u, fast_pair_advertiser_factory_->StartAdvertisingCount());
 
   connection_broker_->StartAdvertising(
-      nullptr,
+      nullptr, /* use_pin_authentication= */ false,
       base::BindOnce(
           &TargetDeviceConnectionBrokerImplTest::StartAdvertisingResultCallback,
           weak_ptr_factory_.GetWeakPtr()));
@@ -422,7 +464,7 @@
 TEST_F(TargetDeviceConnectionBrokerImplTest,
        StopFastPairAdvertising_BeforeBTAdapterInitialized) {
   connection_broker_->StartAdvertising(
-      nullptr,
+      nullptr, /* use_pin_authentication= */ false,
       base::BindOnce(
           &TargetDeviceConnectionBrokerImplTest::StartAdvertisingResultCallback,
           weak_ptr_factory_.GetWeakPtr()));
@@ -442,7 +484,7 @@
   FinishFetchingBluetoothAdapter();
 
   connection_broker_->StartAdvertising(
-      nullptr,
+      nullptr, /* use_pin_authentication= */ false,
       base::BindOnce(
           &TargetDeviceConnectionBrokerImplTest::StartAdvertisingResultCallback,
           weak_ptr_factory_.GetWeakPtr()));
@@ -542,7 +584,7 @@
   EXPECT_FALSE(fake_nearby_connections_manager_.IsAdvertising());
 
   connection_broker_->StartAdvertising(
-      nullptr,
+      nullptr, /* use_pin_authentication= */ false,
       base::BindOnce(
           &TargetDeviceConnectionBrokerImplTest::StartAdvertisingResultCallback,
           weak_ptr_factory_.GetWeakPtr()));
@@ -561,7 +603,7 @@
   EXPECT_FALSE(fake_nearby_connections_manager_.IsAdvertising());
 
   connection_broker_->StartAdvertising(
-      nullptr,
+      nullptr, /* use_pin_authentication= */ false,
       base::BindOnce(
           &TargetDeviceConnectionBrokerImplTest::StartAdvertisingResultCallback,
           weak_ptr_factory_.GetWeakPtr()));
@@ -573,4 +615,24 @@
   EXPECT_FALSE(start_advertising_callback_success_);
 }
 
+TEST_F(TargetDeviceConnectionBrokerImplTest, GetQRCodeData) {
+  std::string random_session_id = GetRandomSessionId().ToString();
+  std::string encoded_shared_secret(kSharedSecretBase64);
+
+  std::vector<uint8_t> expected_data(std::begin(kBaseUrl), std::end(kBaseUrl));
+  expected_data.insert(expected_data.end(), random_session_id.begin(),
+                       random_session_id.end());
+  expected_data.insert(expected_data.end(), std::begin(kUrlKeyParam),
+                       std::end(kUrlKeyParam));
+  expected_data.insert(expected_data.end(), encoded_shared_secret.begin(),
+                       encoded_shared_secret.end());
+
+  std::vector<uint8_t> actual_data = GetQrCodeData();
+  EXPECT_EQ(expected_data, actual_data);
+}
+
+TEST_F(TargetDeviceConnectionBrokerImplTest, DerivePin) {
+  EXPECT_EQ(kAuthenticationTokenPin, DerivePin());
+}
+
 }  // namespace ash::quick_start
diff --git a/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller.cc b/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller.cc
index 616e73c..293bb98 100644
--- a/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller.cc
+++ b/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller.cc
@@ -8,7 +8,6 @@
 #include "base/containers/contains.h"
 #include "base/functional/bind.h"
 #include "chrome/browser/ash/login/oobe_quick_start/connectivity/authenticated_connection.h"
-#include "chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.h"
 #include "chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.h"
 #include "chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_factory.h"
 #include "chrome/browser/ash/login/oobe_quick_start/oobe_quick_start_pref_names.h"
@@ -83,7 +82,7 @@
 
   status_.step = Step::ADVERTISING;
   connection_broker_->StartAdvertising(
-      this,
+      this, /*use_pin_authentication=*/false,
       base::BindOnce(&TargetDeviceBootstrapController::OnStartAdvertisingResult,
                      weak_ptr_factory_.GetWeakPtr()));
   NotifyObservers();
@@ -116,19 +115,25 @@
   prepare_for_update_on_connection_closed_ = true;
 }
 
-void TargetDeviceBootstrapController::OnIncomingConnectionInitiated(
-    const std::string& source_device_id,
-    base::WeakPtr<IncomingConnection> connection) {
+void TargetDeviceBootstrapController::OnPinVerificationRequested(
+    const std::string& pin) {
   constexpr Step kPossibleSteps[] = {Step::ADVERTISING,
                                      Step::QR_CODE_VERIFICATION};
-  DCHECK(base::Contains(kPossibleSteps, status_.step));
-  if (status_.step == Step::QR_CODE_VERIFICATION) {
-    // New connection came. It should be a different device.
-    DCHECK_NE(source_device_id_, source_device_id);
-  }
-  source_device_id_ = source_device_id;
-  incoming_connection_ = std::move(connection);
-  auto qr_code = GenerateQRCode(incoming_connection_->GetQrCodeData());
+  CHECK(base::Contains(kPossibleSteps, status_.step));
+
+  pin_ = pin;
+  // TODO: display pin
+  status_.step = Step::PIN_VERIFICATION;
+  status_.payload.emplace<absl::monostate>();
+  NotifyObservers();
+}
+
+void TargetDeviceBootstrapController::OnQRCodeVerificationRequested(
+    const std::vector<uint8_t>& qr_code_data) {
+  constexpr Step kPossibleSteps[] = {Step::ADVERTISING};
+  CHECK(base::Contains(kPossibleSteps, status_.step));
+
+  auto qr_code = GenerateQRCode(qr_code_data);
   status_.step = Step::QR_CODE_VERIFICATION;
   status_.payload.emplace<QRCodePixelData>(std::move(qr_code));
   NotifyObservers();
@@ -137,10 +142,8 @@
 void TargetDeviceBootstrapController::OnConnectionAuthenticated(
     const std::string& source_device_id,
     base::WeakPtr<AuthenticatedConnection> connection) {
-  DCHECK_EQ(source_device_id_, source_device_id);
   constexpr Step kPossibleSteps[] = {Step::QR_CODE_VERIFICATION};
-  DCHECK(base::Contains(kPossibleSteps, status_.step));
-  DCHECK(incoming_connection_.WasInvalidated());
+  CHECK(base::Contains(kPossibleSteps, status_.step));
 
   status_.step = Step::CONNECTED;
   status_.payload.emplace<absl::monostate>();
@@ -149,7 +152,6 @@
 
 void TargetDeviceBootstrapController::OnConnectionRejected(
     const std::string& source_device_id) {
-  DCHECK_EQ(source_device_id_, source_device_id);
   status_.step = Step::ERROR;
   status_.payload = ErrorCode::CONNECTION_REJECTED;
   NotifyObservers();
@@ -157,7 +159,6 @@
 
 void TargetDeviceBootstrapController::OnConnectionClosed(
     const std::string& source_device_id) {
-  DCHECK_EQ(source_device_id_, source_device_id);
   status_.step = Step::ERROR;
   status_.payload = ErrorCode::CONNECTION_CLOSED;
   NotifyObservers();
diff --git a/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller.h b/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller.h
index fde09b8..34bbd31 100644
--- a/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller.h
+++ b/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller.h
@@ -19,7 +19,6 @@
 namespace ash::quick_start {
 
 class AuthenticatedConnection;
-class IncomingConnection;
 
 class TargetDeviceBootstrapController
     : public TargetDeviceConnectionBroker::ConnectionLifecycleListener {
@@ -36,6 +35,7 @@
     ERROR,
     ADVERTISING,
     QR_CODE_VERIFICATION,
+    PIN_VERIFICATION,
     CONNECTED,
     GAIA_CREDENTIALS,
   };
@@ -89,9 +89,9 @@
   void PrepareForUpdate();
 
   // TargetDeviceConnectionBroker::ConnectionLifecycleListener:
-  void OnIncomingConnectionInitiated(
-      const std::string& source_device_id,
-      base::WeakPtr<IncomingConnection> connection) override;
+  void OnPinVerificationRequested(const std::string& pin) override;
+  void OnQRCodeVerificationRequested(
+      const std::vector<uint8_t>& qr_code_data) override;
   void OnConnectionAuthenticated(
       const std::string& source_device_id,
       base::WeakPtr<AuthenticatedConnection> connection) override;
@@ -104,8 +104,7 @@
   void OnStopAdvertising();
   std::unique_ptr<TargetDeviceConnectionBroker> connection_broker_;
 
-  std::string source_device_id_;
-  base::WeakPtr<IncomingConnection> incoming_connection_;
+  std::string pin_;
   // TODO: Should we enforce one observer at a time here too?
   base::ObserverList<Observer> observers_;
   bool prepare_for_update_on_connection_closed_ = false;
diff --git a/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller_unittest.cc b/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller_unittest.cc
index 3ce5256..d50ece5 100644
--- a/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller_unittest.cc
+++ b/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller_unittest.cc
@@ -127,7 +127,7 @@
   EXPECT_EQ(fake_observer_->last_status.step, Step::NONE);
 }
 
-TEST_F(TargetDeviceBootstrapControllerTest, InitiateConnection) {
+TEST_F(TargetDeviceBootstrapControllerTest, InitiateConnection_QRCode) {
   bootstrap_controller_->StartAdvertising();
   connection_broker()->on_start_advertising_callback().Run(/*success=*/true);
   ASSERT_EQ(fake_observer_->last_status.step, Step::ADVERTISING);
@@ -140,6 +140,20 @@
       fake_observer_->last_status.payload));
 }
 
+TEST_F(TargetDeviceBootstrapControllerTest, InitiateConnection_Pin) {
+  connection_broker()->set_use_pin_authentication(true);
+  bootstrap_controller_->StartAdvertising();
+  connection_broker()->on_start_advertising_callback().Run(/*success=*/true);
+  ASSERT_EQ(fake_observer_->last_status.step, Step::ADVERTISING);
+
+  connection_broker()->InitiateConnection(kSourceDeviceId);
+
+  EXPECT_EQ(fake_observer_->last_status.step, Step::PIN_VERIFICATION);
+  // TODO: Test PIN payload
+  EXPECT_TRUE(absl::holds_alternative<absl::monostate>(
+      fake_observer_->last_status.payload));
+}
+
 TEST_F(TargetDeviceBootstrapControllerTest, AuthenticateConnection) {
   bootstrap_controller_->StartAdvertising();
   connection_broker()->on_start_advertising_callback().Run(/*success=*/true);
diff --git a/chrome/browser/ash/login/screens/quick_start_screen.cc b/chrome/browser/ash/login/screens/quick_start_screen.cc
index 051c66b21..acea141 100644
--- a/chrome/browser/ash/login/screens/quick_start_screen.cc
+++ b/chrome/browser/ash/login/screens/quick_start_screen.cc
@@ -85,6 +85,7 @@
       SavePhoneInstanceID();
       return;
     }
+    case Step::PIN_VERIFICATION:
     case Step::NONE:
     case Step::ERROR:
     case Step::ADVERTISING:
diff --git a/chrome/browser/ash/policy/networking/network_policy_application_browsertest.cc b/chrome/browser/ash/policy/networking/network_policy_application_browsertest.cc
index 15a025d..3eb91f2 100644
--- a/chrome/browser/ash/policy/networking/network_policy_application_browsertest.cc
+++ b/chrome/browser/ash/policy/networking/network_policy_application_browsertest.cc
@@ -83,45 +83,6 @@
 constexpr char kOncRecommendedFieldsWorkaroundActionHistogram[] =
     "Network.Ethernet.Policy.OncRecommendedFieldsWorkaroundAction";
 
-// A utility to wait until a FakeShillServiceClient's service has been
-// connected.
-// Usage:
-// (1) Construct a ServiceConnectedWaiter, specifying the shill service path
-//     that is expected to connect.
-// (2) Call ServiceConnectedWaiter::Wait
-// Wait will return when the service passed to (1) connects. If the service has
-// connected between (1) and (2), Wait returns immediately. Note that this class
-// does not evaluate whether the service was connected before (1).
-class ServiceConnectedWaiter {
- public:
-  ServiceConnectedWaiter(
-      ash::ShillServiceClient::TestInterface* shill_service_client_test,
-      const std::string& service_path)
-      : shill_service_client_test_(shill_service_client_test),
-        service_path_(service_path) {
-    shill_service_client_test_->SetConnectBehavior(service_path_,
-                                                   run_loop_.QuitClosure());
-  }
-
-  ServiceConnectedWaiter(const ServiceConnectedWaiter&) = delete;
-  ServiceConnectedWaiter& operator=(const ServiceConnectedWaiter&) = delete;
-
-  // Waits until the |service_path| passed to the constructor has connected.
-  // If it has connected since the constructor has run, will return immediately.
-  void Wait() {
-    run_loop_.Run();
-    shill_service_client_test_->SetServiceProperty(
-        service_path_, shill::kStateProperty, base::Value(shill::kStateOnline));
-    shill_service_client_test_->SetConnectBehavior(service_path_,
-                                                   base::RepeatingClosure());
-  }
-
- private:
-  ash::ShillServiceClient::TestInterface* shill_service_client_test_;
-  std::string service_path_;
-  base::RunLoop run_loop_;
-};
-
 // Records all values that shill service property had during the lifetime of
 // ServicePropertyValueWatcher. Only supports string properties at the moment.
 class ServicePropertyValueWatcher : public ash::ShillPropertyChangedObserver {
@@ -223,6 +184,28 @@
   absl::optional<WaitForValueState> wait_for_value_state_;
 };
 
+// Shorthand for ServicePropertyValueWatcher that allows waiting for a specific
+// shill::kStateProperty value.
+class ServiceStateWaiter {
+ public:
+  ServiceStateWaiter(
+      ash::ShillServiceClient::TestInterface* shill_service_client_test,
+      const std::string& service_path)
+      : property_value_watcher_(shill_service_client_test,
+                                service_path,
+                                shill::kStateProperty) {}
+
+  ServiceStateWaiter(const ServiceStateWaiter&) = delete;
+  ServiceStateWaiter& operator=(const ServiceStateWaiter&) = delete;
+
+  void Wait(const std::string& expected_state) {
+    property_value_watcher_.WaitForValue(expected_state);
+  }
+
+ private:
+  ServicePropertyValueWatcher property_value_watcher_;
+};
+
 // Registers itself as ash::NetworkPolicyObserver and records events for
 // ash::NetworkPolicyObserver::PoliciesApplied and
 // ash::NetworkPolicyObserver::PolicyAppliedtoNetwork.
@@ -848,11 +831,11 @@
         }
       ]
     })";
-  ServiceConnectedWaiter wifi_one_connected_waiter(shill_service_client_test_,
-                                                   kServiceWifi1);
+  ServiceStateWaiter wifi_one_connected_waiter(shill_service_client_test_,
+                                               kServiceWifi1);
   shill_manager_client_test_->SetBestServiceToConnect(kServiceWifi1);
   SetDeviceOpenNetworkConfiguration(kDeviceONC, /*wait_applied=*/true);
-  wifi_one_connected_waiter.Wait();
+  wifi_one_connected_waiter.Wait(shill::kStateOnline);
 
   EXPECT_THAT(
       network_policy_application_observer.policy_applied_to_network_events(),
@@ -1051,11 +1034,10 @@
           ]
         })";
 
-    ServiceConnectedWaiter wifi_one_connected_waiter(shill_client,
-                                                     kServiceWifi1);
+    ServiceStateWaiter wifi_one_connected_waiter(shill_client, kServiceWifi1);
     shill_manager_client_test_->SetBestServiceToConnect(kServiceWifi1);
     SetDeviceOpenNetworkConfiguration(kDeviceONC, /*wait_applied=*/true);
-    wifi_one_connected_waiter.Wait();
+    wifi_one_connected_waiter.Wait(shill::kStateOnline);
   }
 
   // Check before login that device can connect to any available network.
@@ -1310,12 +1292,12 @@
     absl::optional<std::string> user_policy_wifi_service_path =
         shill_service_client_test_->FindServiceMatchingGUID("wifi_policy_2");
     ASSERT_TRUE(user_policy_wifi_service_path);
-    ServiceConnectedWaiter wifi_connected_waiter(
+    ServiceStateWaiter wifi_connected_waiter(
         shill_service_client_test_, user_policy_wifi_service_path.value());
     SetServiceVisibility("wifi_policy_2", true);
     SimulateWifiScanCompleted();
 
-    wifi_connected_waiter.Wait();
+    wifi_connected_waiter.Wait(shill::kStateOnline);
   }
 
   // Expects that the non-policy WiFi services are now prohibited.
@@ -1409,8 +1391,8 @@
     absl::optional<std::string> policy_wifi_service_path =
         shill_service_client_test_->FindServiceMatchingGUID("wifi_policy_1");
     ASSERT_TRUE(policy_wifi_service_path);
-    ServiceConnectedWaiter wifi_connected_waiter(
-        shill_service_client_test_, policy_wifi_service_path.value());
+    ServiceStateWaiter wifi_connected_waiter(shill_service_client_test_,
+                                             policy_wifi_service_path.value());
 
     shill_manager_client_test_->SetBestServiceToConnect(
         policy_wifi_service_path.value());
@@ -1418,7 +1400,7 @@
     const std::string user_hash = GetTestUserHash();
     shill_profile_client_test_->AddProfile(kUserProfilePath, user_hash);
 
-    wifi_connected_waiter.Wait();
+    wifi_connected_waiter.Wait(shill::kStateOnline);
   }
 
   // Expects that the non-policy WiFi services are now prohibited.
diff --git a/chrome/browser/autofill/android/save_update_address_profile_prompt_controller.cc b/chrome/browser/autofill/android/save_update_address_profile_prompt_controller.cc
index dfc63c6..46859cc 100644
--- a/chrome/browser/autofill/android/save_update_address_profile_prompt_controller.cc
+++ b/chrome/browser/autofill/android/save_update_address_profile_prompt_controller.cc
@@ -88,11 +88,26 @@
   CHECK(!account_info.IsEmpty())
       << "User must be logged in when address profile is going to be saved to "
          "user's Google Account";
+  // Notify user that their address is saved only in Chrome and can be migrated
+  // to their Google account.
+  if (is_migration_to_account_) {
+    return l10n_util::GetStringFUTF16(
+        IDS_AUTOFILL_ADDRESS_WILL_BE_MIGRATED_TO_ACCOUNT_SOURCE_NOTICE,
+        base::UTF8ToUTF16(account_info.email));
+  }
 
+  // Notify user that their address has already been saved in their Google
+  // account and is only going to be updated there.
+  if (original_profile_) {
+    return l10n_util::GetStringFUTF16(
+        IDS_AUTOFILL_ADDRESS_ALREADY_SAVED_IN_ACCOUNT_SOURCE_NOTICE,
+        base::UTF8ToUTF16(account_info.email));
+  }
+
+  // Notify the user that their address is going to be saved in their Google
+  // account if they accept the prompt.
   return l10n_util::GetStringFUTF16(
-      original_profile_
-          ? IDS_AUTOFILL_ADDRESS_ALREADY_SAVED_IN_ACCOUNT_SOURCE_NOTICE
-          : IDS_AUTOFILL_ADDRESS_WILL_BE_SAVED_IN_ACCOUNT_SOURCE_NOTICE,
+      IDS_AUTOFILL_ADDRESS_WILL_BE_SAVED_IN_ACCOUNT_SOURCE_NOTICE,
       base::UTF8ToUTF16(account_info.email));
 }
 
diff --git a/chrome/browser/autofill/android/save_update_address_profile_prompt_controller_unittest.cc b/chrome/browser/autofill/android/save_update_address_profile_prompt_controller_unittest.cc
index 1cbe25f1..c4de81a7 100644
--- a/chrome/browser/autofill/android/save_update_address_profile_prompt_controller_unittest.cc
+++ b/chrome/browser/autofill/android/save_update_address_profile_prompt_controller_unittest.cc
@@ -40,6 +40,8 @@
               (override));
 };
 
+// TODO(crbug.com/1432561): remove test parameters to avoid conditionals in
+// tests.
 class SaveUpdateAddressProfilePromptControllerTest
     : public ChromeRenderViewHostTestHarness,
       public ::testing::WithParamInterface<
@@ -87,7 +89,7 @@
   bool is_migration_to_account() const { return std::get<1>(GetParam()); }
 
  protected:
-  bool ShouldShowFooter() const;
+  bool ShouldShowSourceNotice() const;
   std::u16string GetExpectedNegativeButtonText() const;
   void SetUpController(bool is_update);
 
@@ -106,7 +108,8 @@
   base::android::JavaParamRef<jobject> mock_caller_{nullptr};
 };
 
-bool SaveUpdateAddressProfilePromptControllerTest::ShouldShowFooter() const {
+bool SaveUpdateAddressProfilePromptControllerTest::ShouldShowSourceNotice()
+    const {
   return is_migration_to_account() ||
          profile_source() == AutofillProfile::Source::kAccount;
 }
@@ -256,10 +259,12 @@
   EXPECT_EQ(GetExpectedNegativeButtonText(),
             controller_->GetNegativeButtonText());
 
-  if (ShouldShowFooter()) {
+  if (ShouldShowSourceNotice()) {
     EXPECT_EQ(
         l10n_util::GetStringFUTF16(
-            IDS_AUTOFILL_ADDRESS_WILL_BE_SAVED_IN_ACCOUNT_SOURCE_NOTICE,
+            is_migration_to_account()
+                ? IDS_AUTOFILL_ADDRESS_WILL_BE_MIGRATED_TO_ACCOUNT_SOURCE_NOTICE
+                : IDS_AUTOFILL_ADDRESS_WILL_BE_SAVED_IN_ACCOUNT_SOURCE_NOTICE,
             base::ASCIIToUTF16(kUserEmail)),
         controller_->GetSourceNotice(identity_test_env_.identity_manager()));
   } else {
@@ -284,10 +289,12 @@
   EXPECT_EQ(GetExpectedNegativeButtonText(),
             controller_->GetNegativeButtonText());
 
-  if (ShouldShowFooter()) {
+  if (ShouldShowSourceNotice()) {
     EXPECT_EQ(
         l10n_util::GetStringFUTF16(
-            IDS_AUTOFILL_ADDRESS_ALREADY_SAVED_IN_ACCOUNT_SOURCE_NOTICE,
+            is_migration_to_account()
+                ? IDS_AUTOFILL_ADDRESS_WILL_BE_MIGRATED_TO_ACCOUNT_SOURCE_NOTICE
+                : IDS_AUTOFILL_ADDRESS_ALREADY_SAVED_IN_ACCOUNT_SOURCE_NOTICE,
             base::ASCIIToUTF16(kUserEmail)),
         controller_->GetSourceNotice(identity_test_env_.identity_manager()));
   } else {
@@ -315,10 +322,12 @@
       u"Underworld\n666 Erebus St.\nApt 8\nElysium, CA 91111\nUnited "
       u"States\n\n16502111111",
       differences.second);
-  if (ShouldShowFooter()) {
+  if (ShouldShowSourceNotice()) {
     EXPECT_EQ(
         l10n_util::GetStringFUTF16(
-            IDS_AUTOFILL_ADDRESS_ALREADY_SAVED_IN_ACCOUNT_SOURCE_NOTICE,
+            is_migration_to_account()
+                ? IDS_AUTOFILL_ADDRESS_WILL_BE_MIGRATED_TO_ACCOUNT_SOURCE_NOTICE
+                : IDS_AUTOFILL_ADDRESS_ALREADY_SAVED_IN_ACCOUNT_SOURCE_NOTICE,
             base::ASCIIToUTF16(kUserEmail)),
         controller_->GetSourceNotice(identity_test_env_.identity_manager()));
   } else {
diff --git a/chrome/browser/chrome_browser_interface_binders.cc b/chrome/browser/chrome_browser_interface_binders.cc
index 81bb885c..0d1aaeb 100644
--- a/chrome/browser/chrome_browser_interface_binders.cc
+++ b/chrome/browser/chrome_browser_interface_binders.cc
@@ -978,6 +978,7 @@
       ash::FirmwareUpdateAppUI, ash::ScanningUI, ash::OSFeedbackUI,
       ash::ShortcutCustomizationAppUI,
       ash::printing::printing_manager::PrintManagementUI,
+      ash::InternetDetailDialogUI,
 #endif
       NewTabPageUI, OmniboxPopupUI, BookmarksSidePanelUI, CustomizeChromeUI>(
       map);
diff --git a/chrome/browser/dips/dips_bounce_detector.cc b/chrome/browser/dips/dips_bounce_detector.cc
index d2112c4..cb6e89f 100644
--- a/chrome/browser/dips/dips_bounce_detector.cc
+++ b/chrome/browser/dips/dips_bounce_detector.cc
@@ -24,6 +24,7 @@
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/navigation_handle_user_data.h"
 #include "services/metrics/public/cpp/ukm_recorder.h"
+#include "third_party/blink/public/mojom/devtools/inspector_issue.mojom.h"
 
 using content::NavigationHandle;
 
@@ -217,7 +218,26 @@
 
 void DIPSWebContentsObserver::EmitDIPSIssue(
     const std::set<std::string>& sites) {
-  // TODO (jdh@): Create a DIPSIssue type and report one from here.
+  if (sites.empty()) {
+    return;
+  }
+
+  auto details = blink::mojom::InspectorIssueDetails::New();
+  auto bounce_tracking_issue_details =
+      blink::mojom::BounceTrackingIssueDetails::New();
+
+  bounce_tracking_issue_details->tracking_sites.reserve(sites.size());
+  for (const auto& site : sites) {
+    bounce_tracking_issue_details->tracking_sites.push_back(site);
+  }
+
+  details->bounce_tracking_issue_details =
+      std::move(bounce_tracking_issue_details);
+
+  web_contents()->GetPrimaryMainFrame()->ReportInspectorIssue(
+      blink::mojom::InspectorIssueInfo::New(
+          blink::mojom::InspectorIssueCode::kBounceTrackingIssue,
+          std::move(details)));
 }
 
 void DIPSWebContentsObserver::ReportRedirectorsWithoutInteraction(
@@ -566,9 +586,15 @@
     redirectors.insert(GetSiteForDIPS(*it));
   }
 
-  // Since redirectors that are the same as the start page won't be acted on,
-  // we don't report on them.
+  // Since redirectors that are the same as the start or final page won't be
+  // acted on, we don't report on them.
+  //
+  // NOTE: This is not exactly right since the end of this navigation may not
+  // necessarily be the end of the chain, if a client redirect happens. However,
+  // this is better for developer experience than waiting until then, since
+  // notifications come faster.
   redirectors.erase(initial_site);
+  redirectors.erase(GetSiteForDIPS(redirect_chain.back()));
 
   return redirectors;
 }
diff --git a/chrome/browser/dips/dips_bounce_detector.h b/chrome/browser/dips/dips_bounce_detector.h
index 8be83a8..73562b93 100644
--- a/chrome/browser/dips/dips_bounce_detector.h
+++ b/chrome/browser/dips/dips_bounce_detector.h
@@ -207,6 +207,7 @@
 
   // Returns the set of sites in the current (server) redirect chain. If the
   // navigation started with a client redirect, that site is also included.
+  // Redirectors matching the initial or end site are omitted.
   std::set<std::string> GetRedirectors(
       const DIPSNavigationStart& navigation_start,
       DIPSNavigationHandle* navigation_handle);
diff --git a/chrome/browser/dips/dips_bounce_detector_browsertest.cc b/chrome/browser/dips/dips_bounce_detector_browsertest.cc
index 3d531d3..5ce7fec0 100644
--- a/chrome/browser/dips/dips_bounce_detector_browsertest.cc
+++ b/chrome/browser/dips/dips_bounce_detector_browsertest.cc
@@ -22,6 +22,7 @@
 #include "content/public/test/browser_test.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/hit_test_region_observer.h"
+#include "content/public/test/test_devtools_protocol_client.h"
 #include "content/public/test/test_utils.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/test/embedded_test_server/http_request.h"
@@ -690,3 +691,84 @@
                            "b.test/cross-site/c.test/title1.html (None) -> "
                            "c.test/title1.html")));
 }
+
+class DIPSBounceTrackingDevToolsIssueTest
+    : public content::TestDevToolsProtocolClient,
+      public DIPSBounceDetectorBrowserTest {
+ protected:
+  void WaitForIssueAndCheckTrackingSites(
+      const std::vector<std::string>& sites) {
+    auto is_dips_issue = [](const base::Value::Dict& params) {
+      return *(params.FindStringByDottedPath("issue.code")) ==
+             "BounceTrackingIssue";
+    };
+
+    // Wait for notification of a Bounce Tracking Issue.
+    base::Value::Dict params = WaitForMatchingNotification(
+        "Audits.issueAdded", base::BindRepeating(is_dips_issue));
+    ASSERT_EQ(*params.FindStringByDottedPath("issue.code"),
+              "BounceTrackingIssue");
+
+    base::Value::Dict* bounce_tracking_issue_details =
+        params.FindDictByDottedPath("issue.details.bounceTrackingIssueDetails");
+    ASSERT_TRUE(bounce_tracking_issue_details);
+
+    std::vector<std::string> tracking_sites;
+    base::Value::List* tracking_sites_list =
+        bounce_tracking_issue_details->FindList("trackingSites");
+    if (tracking_sites_list) {
+      for (const auto& val : *tracking_sites_list) {
+        tracking_sites.push_back(val.GetString());
+      }
+    }
+
+    // Verify the reported tracking sites match the expected sites.
+    EXPECT_THAT(tracking_sites, testing::ElementsAreArray(sites));
+
+    // Clear existing notifications so subsequent calls don't fail by checking
+    // `sites` against old notifications.
+    ClearNotifications();
+  }
+
+  void TearDownOnMainThread() override {
+    DetachProtocolClient();
+    DIPSBounceDetectorBrowserTest::TearDownOnMainThread();
+  }
+};
+
+IN_PROC_BROWSER_TEST_F(DIPSBounceTrackingDevToolsIssueTest,
+                       BounceTrackingDevToolsIssue) {
+  WebContents* web_contents = GetActiveWebContents();
+
+  // Visit initial page on a.test.
+  ASSERT_TRUE(content::NavigateToURL(
+      web_contents, embedded_test_server()->GetURL("a.test", "/title1.html")));
+
+  // Open DevTools and enable Audit domain.
+  AttachToWebContents(web_contents);
+  SendCommandSync("Audits.enable");
+  ClearNotifications();
+
+  // Navigate with a click (not a redirect) to b.test, which S-redirects to
+  // c.test.
+  ASSERT_TRUE(content::NavigateToURLFromRenderer(
+      web_contents,
+      embedded_test_server()->GetURL("b.test",
+                                     "/cross-site/c.test/title1.html"),
+      embedded_test_server()->GetURL("c.test", "/title1.html")));
+  WaitForIssueAndCheckTrackingSites({"b.test"});
+
+  // Navigate without a click (i.e. by C-redirecting) to d.test.
+  ASSERT_TRUE(content::NavigateToURLFromRendererWithoutUserGesture(
+      web_contents, embedded_test_server()->GetURL("d.test", "/title1.html")));
+  WaitForIssueAndCheckTrackingSites({"c.test"});
+
+  // Navigate without a click (i.e. by C-redirecting) to e.test, which
+  // S-redirects to f.test, which S-redirects to g.test.
+  ASSERT_TRUE(content::NavigateToURLFromRendererWithoutUserGesture(
+      web_contents,
+      embedded_test_server()->GetURL(
+          "e.test", "/cross-site/f.test/cross-site/g.test/title1.html"),
+      embedded_test_server()->GetURL("g.test", "/title1.html")));
+  WaitForIssueAndCheckTrackingSites({"d.test", "e.test", "f.test"});
+}
diff --git a/chrome/browser/dips/dips_bounce_detector_unittest.cc b/chrome/browser/dips/dips_bounce_detector_unittest.cc
index cbbeeda..75fec8f 100644
--- a/chrome/browser/dips/dips_bounce_detector_unittest.cc
+++ b/chrome/browser/dips/dips_bounce_detector_unittest.cc
@@ -493,16 +493,17 @@
   StartNavigation("http://b.test", kWithUserGesture)
       .RedirectTo("http://c.test")
       .Finish(true);
+  EXPECT_THAT(GetReportedSites(), testing::ElementsAre("b.test"));
 
   // Navigate without a click (i.e. by C-redirecting) to d.test
   NavigateTo("http://d.test", kNoUserGesture);
+  EXPECT_THAT(GetReportedSites(), testing::ElementsAre("b.test", "c.test"));
 
   // Navigate without a click (i.e. by C-redirecting) to e.test, which
   // S-redirects to f.test
   StartNavigation("http://e.test", kNoUserGesture)
       .RedirectTo("http://f.test")
       .Finish(true);
-
   EXPECT_THAT(GetReportedSites(),
               testing::ElementsAre("b.test", "c.test", "d.test, e.test"));
 }
@@ -517,13 +518,13 @@
       .RedirectTo("http://c.test")
       .RedirectTo("http://d.test")
       .Finish(false);
+  EXPECT_THAT(GetReportedSites(), testing::ElementsAre("b.test, c.test"));
 
   // Because the previous navigation didn't commit, the following chain still
   // starts from http://a.test/.
   StartNavigation("http://e.test", kWithUserGesture)
       .RedirectTo("http://f.test")
       .Finish(true);
-
   EXPECT_THAT(GetReportedSites(),
               testing::ElementsAre("b.test, c.test", "e.test"));
 }
@@ -542,9 +543,11 @@
       .RedirectTo("http://a.test")
       .RedirectTo("http://c.test")
       .Finish(true);
+  EXPECT_THAT(GetReportedSites(), testing::ElementsAre("b.test"));
 
   // Navigate without a click (i.e. by C-redirecting) to a.test.
   NavigateTo("http://a.test", kNoUserGesture);
+  EXPECT_THAT(GetReportedSites(), testing::ElementsAre("b.test", "c.test"));
 
   // Navigate without a click (i.e. by C-redirecting) to d.test, which
   // S-redirects to e.test, which S-redirects to f.test.
@@ -552,11 +555,59 @@
       .RedirectTo("http://e.test")
       .RedirectTo("http://f.test")
       .Finish(true);
-
   EXPECT_THAT(GetReportedSites(),
               testing::ElementsAre("b.test", "c.test", "d.test, e.test"));
 }
 
+// This test verifies that sites in a (server) redirect chain that are the same
+// as the ending site of a navigation are not reported.
+TEST_F(DIPSBounceDetectorTest,
+       ReportRedirectorsInChain_OmitSitesMatchingEndSite) {
+  // Visit initial page on a.test.
+  NavigateTo("http://a.test", kWithUserGesture);
+
+  // Navigate with a click (not a redirect) to b.test, which S-redirects to
+  // c.test, which S-redirects to c.test.
+  StartNavigation("http://b.test", kWithUserGesture)
+      .RedirectTo("http://c.test")
+      .RedirectTo("http://c.test")
+      .Finish(true);
+  EXPECT_THAT(GetReportedSites(), testing::ElementsAre("b.test"));
+
+  // Navigate without a click (i.e. by C-redirecting) to d.test.
+  NavigateTo("http://d.test", kNoUserGesture);
+  EXPECT_THAT(GetReportedSites(), testing::ElementsAre("b.test", "c.test"));
+
+  // Navigate without a click (i.e. by C-redirecting) to e.test, which
+  // S-redirects to f.test, which S-redirects to e.test.
+  StartNavigation("http://e.test", kNoUserGesture)
+      .RedirectTo("http://f.test")
+      .RedirectTo("http://e.test")
+      .Finish(true);
+  EXPECT_THAT(GetReportedSites(),
+              testing::ElementsAre("b.test", "c.test", "d.test, f.test"));
+}
+
+TEST_F(DIPSBounceDetectorTest,
+       ReportRedirectorsInChain_OmitSitesMatchingEndSite_Uncommitted) {
+  // Visit initial page on a.test.
+  NavigateTo("http://a.test", kWithUserGesture);
+
+  // Navigate with a click (not a redirect) to b.test, which S-redirects to
+  // c.test, which S-redirects to c.test.
+  StartNavigation("http://b.test", kWithUserGesture)
+      .RedirectTo("http://c.test")
+      .RedirectTo("http://c.test")
+      .Finish(false);
+  EXPECT_THAT(GetReportedSites(), testing::ElementsAre("b.test"));
+
+  // Navigate without a click (i.e. by C-redirecting) to d.test.
+  // NOTE: Because the previous navigation didn't commit, the chain still
+  // starts from http://a.test/.
+  NavigateTo("http://d.test", kNoUserGesture);
+  EXPECT_THAT(GetReportedSites(), testing::ElementsAre("b.test", "a.test"));
+}
+
 TEST_F(DIPSBounceDetectorTest, InteractionRecording_Throttled) {
   base::Time first_time = GetCurrentTime();
   NavigateTo("http://a.test", kNoUserGesture);
diff --git a/chrome/browser/extensions/extension_browsertest.cc b/chrome/browser/extensions/extension_browsertest.cc
index 5b3ae149..1470754e 100644
--- a/chrome/browser/extensions/extension_browsertest.cc
+++ b/chrome/browser/extensions/extension_browsertest.cc
@@ -299,8 +299,8 @@
       set_chromeos_user_(true),
 #endif
       context_type_(context_type),
-      // Default channel is STABLE but override with UNKNOWN so that unlaunched
-      // or incomplete APIs can write tests.
+      // TODO(crbug/1427323): Move this ScopedCurrentChannel down into tests
+      // that specifically require it.
       current_channel_(version_info::Channel::UNKNOWN),
       override_prompt_for_external_extensions_(
           FeatureSwitch::prompt_for_external_extensions(),
diff --git a/chrome/browser/extensions/extension_browsertest.h b/chrome/browser/extensions/extension_browsertest.h
index f8990a0..d0ed5ed 100644
--- a/chrome/browser/extensions/extension_browsertest.h
+++ b/chrome/browser/extensions/extension_browsertest.h
@@ -423,7 +423,13 @@
       bool wait_for_idle,
       bool grant_permissions);
 
-  // Make the current channel "dev" for the duration of the test.
+  // Used for setting the default scoped current channel for extension browser
+  // tests to UNKNOWN (trunk), in order to enable channel restricted features.
+  // TODO(crbug/1427323): We should remove this and have the current channel
+  // respect what is defined on the builder. If a test requires a specific
+  // channel for a channel restricted feature, it should be defining its own
+  // scoped channel override. As this stands, it means we don't really have
+  // non-trunk coverage for most extension browser tests.
   ScopedCurrentChannel current_channel_;
 
   // Disable external install UI.
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 923883bc..2612a55 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -7061,6 +7061,11 @@
     "expiry_milestone": 114
   },
   {
+    "name": "sync-segments-data",
+    "owners": [ "bwwilliams", "sky", "treib" ],
+    "expiry_milestone": 130
+  },
+  {
     "name": "sync-standalone-invalidations",
     "owners": [ "treib", "rushans" ],
     "expiry_milestone": 115
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
index 7199429..71a2557 100644
--- a/chrome/browser/flags/android/chrome_feature_list.cc
+++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -262,7 +262,6 @@
     &kOmniboxConsumesImeInsets,
     &kOmniboxModernizeVisualUpdate,
     &kOpaqueOriginForIncomingIntents,
-    &kOptimizeGeolocationHeaderGeneration,
     &kPartnerHomepageInitialLoadImprovement,
     &kProbabilisticCryptidRenderer,
     &kQuickDeleteForAndroid,
@@ -848,10 +847,6 @@
              "OpaqueOriginForIncomingIntents",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
-BASE_FEATURE(kOptimizeGeolocationHeaderGeneration,
-             "OptimizeGeolocationHeaderGeneration",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-
 BASE_FEATURE(kPartnerHomepageInitialLoadImprovement,
              "PartnerHomepageInitialLoadImprovement",
              base::FEATURE_ENABLED_BY_DEFAULT);
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 9c079d8..67e59135 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
@@ -395,8 +395,6 @@
             "OpaqueOriginForIncomingIntents";
     public static final String OPTIMIZATION_GUIDE_PUSH_NOTIFICATIONS =
             "OptimizationGuidePushNotifications";
-    public static final String OPTIMIZE_GEOLOCATION_HEADER_GENERATION =
-            "OptimizeGeolocationHeaderGeneration";
     public static final String PAGE_ANNOTATIONS_SERVICE = "PageAnnotationsService";
     public static final String PAGE_INFO_ABOUT_THIS_SITE_EN = "PageInfoAboutThisSiteEn";
     public static final String PAGE_INFO_ABOUT_THIS_SITE_IMPROVED_BOTTOMSHEET =
diff --git a/chrome/browser/lacros/cert/cert_db_initializer_factory.cc b/chrome/browser/lacros/cert/cert_db_initializer_factory.cc
index c6a5892a..8c2549a 100644
--- a/chrome/browser/lacros/cert/cert_db_initializer_factory.cc
+++ b/chrome/browser/lacros/cert/cert_db_initializer_factory.cc
@@ -8,7 +8,6 @@
 #include "base/system/sys_info.h"
 #include "chrome/browser/lacros/cert/cert_db_initializer_impl.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/signin/identity_manager_factory.h"
 #include "chromeos/lacros/lacros_service.h"
 
 class CertDbInitializer;
@@ -29,9 +28,7 @@
 CertDbInitializerFactory::CertDbInitializerFactory()
     : ProfileKeyedServiceFactory(
           "CertDbInitializerFactory",
-          ProfileSelections::BuildRedirectedInIncognito()) {
-  DependsOn(IdentityManagerFactory::GetInstance());
-}
+          ProfileSelections::BuildRedirectedInIncognito()) {}
 
 bool CertDbInitializerFactory::ServiceIsCreatedWithBrowserContext() const {
   return should_create_with_browser_context_;
diff --git a/chrome/browser/media/cast_mirroring_service_host.cc b/chrome/browser/media/cast_mirroring_service_host.cc
index eea6301d..2672bffb 100644
--- a/chrome/browser/media/cast_mirroring_service_host.cc
+++ b/chrome/browser/media/cast_mirroring_service_host.cc
@@ -72,6 +72,10 @@
 // Default resolution constraint.
 constexpr gfx::Size kMaxResolution(1920, 1080);
 
+// The delay before calling PauseVideoCaptureHostOnIO. This allows us to ensure
+// UI elements are hidden before we stop sending frames.
+constexpr base::TimeDelta kPauseDelay = base::Milliseconds(500);
+
 // Command line arguments that should be passed to the mirroring service.
 static const char* kPassthroughSwitches[]{
     switches::kCastStreamingForceEnableHardwareH264,
@@ -612,9 +616,11 @@
 void CastMirroringServiceHost::Pause() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (freeze_ui_enabled_ && video_capture_host_) {
-    content::GetIOThreadTaskRunner({})->PostTask(
-        FROM_HERE, base::BindOnce(&PauseVideoCaptureHostOnIO,
-                                  video_capture_host_->impl(), ignored_token_));
+    content::GetIOThreadTaskRunner({})->PostDelayedTask(
+        FROM_HERE,
+        base::BindOnce(&PauseVideoCaptureHostOnIO, video_capture_host_->impl(),
+                       ignored_token_),
+        kPauseDelay);
   }
 }
 
diff --git a/chrome/browser/media/router/providers/cast/mirroring_activity.cc b/chrome/browser/media/router/providers/cast/mirroring_activity.cc
index b8fcecd..d99da3f 100644
--- a/chrome/browser/media/router/providers/cast/mirroring_activity.cc
+++ b/chrome/browser/media/router/providers/cast/mirroring_activity.cc
@@ -450,6 +450,10 @@
     mojo::PendingReceiver<mojom::MediaController> media_controller,
     mojo::PendingRemote<mojom::MediaStatusObserver> observer) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(io_sequence_checker_);
+  media_controller_receiver_.reset();
+  media_controller_receiver_.Bind(std::move(media_controller));
+  media_status_observer_.reset();
+  media_status_observer_.Bind(std::move(observer));
 }
 
 std::string MirroringActivity::GetRouteDescription(
@@ -666,4 +670,22 @@
   debugger_->OnMirroringStats(json_stats.Clone());
 }
 
+void MirroringActivity::Play() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_sequence_checker_);
+  if (host_) {
+    content::GetUIThreadTaskRunner({})->PostTask(
+        FROM_HERE, base::BindOnce(&mirroring::MirroringServiceHost::Resume,
+                                  host_->GetWeakPtr()));
+  }
+}
+
+void MirroringActivity::Pause() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_sequence_checker_);
+  if (host_) {
+    content::GetUIThreadTaskRunner({})->PostTask(
+        FROM_HERE, base::BindOnce(&mirroring::MirroringServiceHost::Pause,
+                                  host_->GetWeakPtr()));
+  }
+}
+
 }  // namespace media_router
diff --git a/chrome/browser/media/router/providers/cast/mirroring_activity.h b/chrome/browser/media/router/providers/cast/mirroring_activity.h
index a5bf9cf..7224163e 100644
--- a/chrome/browser/media/router/providers/cast/mirroring_activity.h
+++ b/chrome/browser/media/router/providers/cast/mirroring_activity.h
@@ -19,7 +19,9 @@
 #include "components/media_router/common/media_route.h"
 #include "components/media_router/common/mojom/debugger.mojom.h"
 #include "components/media_router/common/mojom/logger.mojom.h"
+#include "components/media_router/common/mojom/media_controller.mojom.h"
 #include "components/media_router/common/mojom/media_router.mojom-forward.h"
+#include "components/media_router/common/mojom/media_status.mojom.h"
 #include "components/media_router/common/providers/cast/channel/cast_message_handler.h"
 #include "components/mirroring/mojom/cast_message_channel.mojom.h"
 #include "components/mirroring/mojom/session_observer.mojom.h"
@@ -37,7 +39,8 @@
 
 class MirroringActivity : public CastActivity,
                           public mirroring::mojom::SessionObserver,
-                          public mirroring::mojom::CastMessageChannel {
+                          public mirroring::mojom::CastMessageChannel,
+                          public mojom::MediaController {
  public:
   using OnStopCallback = base::OnceClosure;
 
@@ -80,6 +83,21 @@
   void OnAppMessage(const cast::channel::CastMessage& message) override;
   void OnInternalMessage(const cast_channel::InternalMessage& message) override;
 
+  // mojom::MediaController implementation
+  void SetMute(bool mute) override {}
+  void SetVolume(float volume) override {}
+  void Seek(base::TimeDelta time) override {}
+  void NextTrack() override {}
+  void PreviousTrack() override {}
+  // Used during access code casting to resume the mirroring session, if
+  // frozen. This will send a request to the video capture host to resume
+  // displaying the casting session.
+  void Play() override;
+  // Used during access code casting to freeze the mirroring session. This will
+  // send a request to the video capture host to pause the display of the
+  // mirroring session.
+  void Pause() override;
+
   mirroring::MirroringServiceHost* GetHost() {
     DCHECK_CALLED_ON_VALID_SEQUENCE(ui_sequence_checker_);
     return host_.get();
@@ -161,6 +179,14 @@
   // receiver.
   mojo::Receiver<mirroring::mojom::CastMessageChannel> channel_receiver_{this};
 
+  // To handle freeze and unfreeze requests from the mirroring media controller
+  // host to the mirroring service host.
+  mojo::Receiver<mojom::MediaController> media_controller_receiver_{this};
+
+  // Sends media status updates with mirroring information needed for freezing
+  // the session.
+  mojo::Remote<mojom::MediaStatusObserver> media_status_observer_;
+
   // Set before and after a mirroring session is established, for metrics.
   absl::optional<base::Time> will_start_mirroring_timestamp_;
   absl::optional<base::Time> did_start_mirroring_timestamp_;
diff --git a/chrome/browser/media/router/providers/cast/mirroring_activity_unittest.cc b/chrome/browser/media/router/providers/cast/mirroring_activity_unittest.cc
index 175da55..f50a4b81 100644
--- a/chrome/browser/media/router/providers/cast/mirroring_activity_unittest.cc
+++ b/chrome/browser/media/router/providers/cast/mirroring_activity_unittest.cc
@@ -533,4 +533,18 @@
   RunUntilIdle();
 }
 
+TEST_F(MirroringActivityTest, Pause) {
+  MakeActivity();
+
+  EXPECT_CALL(*mirroring_service_, Pause()).Times(testing::Exactly(1));
+  activity_->Pause();
+}
+
+TEST_F(MirroringActivityTest, Play) {
+  MakeActivity();
+
+  EXPECT_CALL(*mirroring_service_, Resume()).Times(testing::Exactly(1));
+  activity_->Play();
+}
+
 }  // namespace media_router
diff --git a/chrome/browser/media/router/providers/cast/mock_mirroring_activity.h b/chrome/browser/media/router/providers/cast/mock_mirroring_activity.h
index 28e886f..c0d28ce 100644
--- a/chrome/browser/media/router/providers/cast/mock_mirroring_activity.h
+++ b/chrome/browser/media/router/providers/cast/mock_mirroring_activity.h
@@ -23,6 +23,14 @@
   MOCK_METHOD(void,
               SendStopSessionMessageToClients,
               (const std::string& hash_token));
+
+  MOCK_METHOD(void, Play, ());
+  MOCK_METHOD(void, Pause, ());
+  MOCK_METHOD(void, SetMute, (bool mute));
+  MOCK_METHOD(void, SetVolume, (float volume));
+  MOCK_METHOD(void, Seek, (base::TimeDelta time));
+  MOCK_METHOD(void, NextTrack, ());
+  MOCK_METHOD(void, PreviousTrack, ());
 };
 
 }  // namespace media_router
diff --git a/chrome/browser/media/webrtc/capture_policy_utils.cc b/chrome/browser/media/webrtc/capture_policy_utils.cc
index 5556863..2bbc78e 100644
--- a/chrome/browser/media/webrtc/capture_policy_utils.cc
+++ b/chrome/browser/media/webrtc/capture_policy_utils.cc
@@ -49,12 +49,14 @@
   // aligns better than URLMatcher with the rules from:
   // https://chromeenterprise.google/policies/url-patterns/.
   for (const auto& value : allowed_origins) {
-    if (!value.is_string())
+    if (!value.is_string()) {
       continue;
+    }
     ContentSettingsPattern pattern =
         ContentSettingsPattern::FromString(value.GetString());
-    if (pattern.IsValid() && pattern.Matches(request_origin))
+    if (pattern.IsValid() && pattern.Matches(request_origin)) {
       return true;
+    }
   }
 
   return false;
@@ -76,12 +78,14 @@
   // If we can't get the PrefService, then we won't apply any restrictions.
   Profile* profile =
       Profile::FromBrowserContext(capturer_web_contents->GetBrowserContext());
-  if (!profile)
+  if (!profile) {
     return AllowedScreenCaptureLevel::kUnrestricted;
+  }
 
   const PrefService* prefs = profile->GetPrefs();
-  if (!prefs)
+  if (!prefs) {
     return AllowedScreenCaptureLevel::kUnrestricted;
+  }
 
   return GetAllowedCaptureLevel(request_origin, *prefs);
 }
@@ -126,6 +130,16 @@
   if (!profile) {
     return false;
   }
+
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // To ensure that a user is informed at login time that capturing of all
+  // screens can happen (for privacy reasons), this API is only available on
+  // primary profiles.
+  if (!profile->IsMainProfile()) {
+    return false;
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
   HostContentSettingsMap* host_content_settings_map =
       HostContentSettingsMapFactory::GetForProfile(profile);
   if (!host_content_settings_map) {
@@ -150,12 +164,24 @@
     const GURL& url) {
 #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
   Profile* profile = Profile::FromBrowserContext(context);
-  if (!profile)
+  if (!profile) {
     return false;
+  }
+
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // To ensure that a user is informed at login time that capturing of all
+  // screens can happen (for privacy reasons), this API is only available on
+  // primary profiles.
+  if (!profile->IsMainProfile()) {
+    return false;
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
   HostContentSettingsMap* host_content_settings_map =
       HostContentSettingsMapFactory::GetForProfile(profile);
-  if (!host_content_settings_map)
+  if (!host_content_settings_map) {
     return false;
+  }
   ContentSetting auto_accept_enabled =
       host_content_settings_map->GetContentSetting(
           url, url,
diff --git a/chrome/browser/media/webrtc/capture_policy_utils_unittest.cc b/chrome/browser/media/webrtc/capture_policy_utils_unittest.cc
index 7d964aa9..4b07d40 100644
--- a/chrome/browser/media/webrtc/capture_policy_utils_unittest.cc
+++ b/chrome/browser/media/webrtc/capture_policy_utils_unittest.cc
@@ -4,11 +4,16 @@
 
 #include "chrome/browser/media/webrtc/capture_policy_utils.h"
 
+#include "base/containers/contains.h"
 #include "base/values.h"
+#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
 #include "chrome/common/pref_names.h"
+#include "chrome/test/base/testing_profile.h"
+#include "components/content_settings/core/browser/host_content_settings_map.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 #include "components/prefs/testing_pref_service.h"
+#include "content/public/test/browser_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
@@ -255,3 +260,90 @@
 
   EXPECT_EQ(expected_media_types, actual_media_types);
 }
+
+#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
+
+class MultiCaptureTest
+    : public testing::Test,
+      public ::testing::WithParamInterface<
+          std::tuple<bool, std::vector<std::string>, std::string>> {
+ public:
+  void SetUp() override {
+    testing::Test::SetUp();
+
+    TestingProfile::Builder builder;
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+    builder.SetIsMainProfile(IsMainProfile());
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+    profile_ = builder.Build();
+
+    HostContentSettingsMap* content_settings =
+        HostContentSettingsMapFactory::GetForProfile(profile());
+    for (const std::string& url : AllowedOrigins()) {
+      content_settings->SetContentSettingDefaultScope(
+          GURL(url), GURL(url),
+          ContentSettingsType::GET_DISPLAY_MEDIA_SET_SELECT_ALL_SCREENS,
+          ContentSetting::CONTENT_SETTING_ALLOW);
+    }
+  }
+
+  void TearDown() override { profile_.reset(); }
+
+  Profile* profile() { return profile_.get(); }
+  bool IsMainProfile() const { return std::get<0>(GetParam()); }
+  std::vector<std::string> AllowedOrigins() const {
+    return std::get<1>(GetParam());
+  }
+  std::string CurrentOrigin() const { return std::get<2>(GetParam()); }
+
+ protected:
+  bool ExpectedIsMultiCaptureAllowed() {
+    std::vector<std::string> allowed_urls = AllowedOrigins();
+    return
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+        IsMainProfile() &&
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+        base::Contains(allowed_urls, CurrentOrigin());
+  }
+
+  bool ExpectedIsMultiCaptureAllowedForAnyUrl() {
+    return
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+        IsMainProfile() &&
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+        !AllowedOrigins().empty();
+  }
+
+ private:
+  std::unique_ptr<TestingProfile> profile_;
+  content::BrowserTaskEnvironment task_environment_;
+};
+
+TEST_P(MultiCaptureTest, IsMultiCaptureAllowedBasedOnPolicy) {
+  EXPECT_EQ(ExpectedIsMultiCaptureAllowed(),
+            capture_policy::IsGetDisplayMediaSetSelectAllScreensAllowed(
+                profile(), GURL(CurrentOrigin())));
+}
+
+TEST_P(MultiCaptureTest, IsMultiCaptureAllowedForAnyUrl) {
+  EXPECT_EQ(
+      ExpectedIsMultiCaptureAllowedForAnyUrl(),
+      capture_policy::IsGetDisplayMediaSetSelectAllScreensAllowedForAnySite(
+          profile()));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    MultiCaptureTestCases,
+    MultiCaptureTest,
+    ::testing::Combine(
+        // Is main profile?
+        ::testing::Bool(),
+        // Allowed origins
+        ::testing::ValuesIn({std::vector<std::string>{},
+                             std::vector<std::string>{
+                                 "https://www.google.com"}}),
+        // Origin to test
+        ::testing::ValuesIn({std::string("https://www.google.com"),
+                             std::string("https://www.notallowed.com")})));
+
+#endif  // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
diff --git a/chrome/browser/profiles/profile_window.cc b/chrome/browser/profiles/profile_window.cc
index 7f74410..e6ba3b4 100644
--- a/chrome/browser/profiles/profile_window.cc
+++ b/chrome/browser/profiles/profile_window.cc
@@ -245,24 +245,40 @@
 BrowserAddedForProfileObserver::BrowserAddedForProfileObserver(
     Profile* profile,
     base::OnceClosure callback)
-    : profile_(profile), callback_(std::move(callback)) {
+    : profile_(profile->GetWeakPtr()), callback_(std::move(callback)) {
   DCHECK(callback_);
-  BrowserList::AddObserver(this);
+  browser_list_observation_.Observe(BrowserList::GetInstance());
 }
 
 BrowserAddedForProfileObserver::~BrowserAddedForProfileObserver() {}
 
 void BrowserAddedForProfileObserver::OnBrowserAdded(Browser* browser) {
-  if (browser->profile() == profile_) {
-    BrowserList::RemoveObserver(this);
+  if (browser->profile() == profile_.get()) {
+    browser_ = browser;
     // By the time the browser is added a tab (or multiple) are about to be
     // added. Post the callback to the message loop so it gets executed after
     // the tabs are created.
     base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
-        FROM_HERE, std::move(callback_));
-    base::SingleThreadTaskRunner::GetCurrentDefault()->DeleteSoon(FROM_HERE,
-                                                                  this);
+        FROM_HERE,
+        base::BindOnce(
+            &BrowserAddedForProfileObserver::NotifyBrowserCreatedAnDie,
+            base::Unretained(this)));
   }
 }
 
+void BrowserAddedForProfileObserver::OnBrowserRemoved(Browser* browser) {
+  // The browser was closed before the callback could run.
+  if (browser == browser_) {
+    browser_list_observation_.Reset();
+    browser_ = nullptr;
+  }
+}
+
+void BrowserAddedForProfileObserver::NotifyBrowserCreatedAnDie() {
+  if (browser_) {
+    std::move(callback_).Run();
+  }
+  delete this;
+}
+
 }  // namespace profiles
diff --git a/chrome/browser/profiles/profile_window.h b/chrome/browser/profiles/profile_window.h
index c5e3066..5a7f582 100644
--- a/chrome/browser/profiles/profile_window.h
+++ b/chrome/browser/profiles/profile_window.h
@@ -17,6 +17,7 @@
 #error "Not used on Android"
 #endif
 
+class BrowserList;
 class Profile;
 
 namespace base { class FilePath; }
@@ -89,10 +90,16 @@
  private:
   // Overridden from BrowserListObserver:
   void OnBrowserAdded(Browser* browser) override;
+  void OnBrowserRemoved(Browser* browser) override;
+
+  void NotifyBrowserCreatedAnDie();
 
   // Profile for which the browser should be opened.
-  raw_ptr<Profile> profile_;
+  base::WeakPtr<Profile> profile_;
+  raw_ptr<Browser> browser_ = nullptr;
   base::OnceClosure callback_;
+  base::ScopedObservation<BrowserList, BrowserListObserver>
+      browser_list_observation_{this};
 };
 
 }  // namespace profiles
diff --git a/chrome/browser/profiles/profile_window_browsertest.cc b/chrome/browser/profiles/profile_window_browsertest.cc
index afdea65..57529f942 100644
--- a/chrome/browser/profiles/profile_window_browsertest.cc
+++ b/chrome/browser/profiles/profile_window_browsertest.cc
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/memory/raw_ptr.h"
 #include "chrome/browser/profiles/profile_window.h"
 
 #include <stddef.h>
@@ -10,8 +9,11 @@
 
 #include "base/command_line.h"
 #include "base/functional/bind.h"
+#include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/bind.h"
+#include "base/test/test_future.h"
 #include "base/values.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
@@ -100,6 +102,23 @@
   }
 };
 
+class BrowserAddedObserver : public BrowserListObserver {
+ public:
+  explicit BrowserAddedObserver(base::OnceCallback<void(Browser*)> callback)
+      : callback_(std::move(callback)) {
+    CHECK(callback_);
+    BrowserList::AddObserver(this);
+  }
+
+  void OnBrowserAdded(Browser* browser) override {
+    BrowserList::RemoveObserver(this);
+    std::move(callback_).Run(browser);
+  }
+
+ private:
+  base::OnceCallback<void(Browser*)> callback_;
+};
+
 }  // namespace
 
 class ProfileWindowBrowserTest : public InProcessBrowserTest {
@@ -309,13 +328,36 @@
 IN_PROC_BROWSER_TEST_F(ProfileWindowBrowserTest, OpenBrowserWindowForProfile) {
   Profile* profile = browser()->profile();
   size_t num_browsers = BrowserList::GetInstance()->size();
-  profiles::OpenBrowserWindowForProfile(base::OnceCallback<void(Profile*)>(),
-                                        true, false, false, profile);
-  base::RunLoop().RunUntilIdle();
+  base::test::TestFuture<Profile*> future;
+  profiles::OpenBrowserWindowForProfile(future.GetCallback(), true, false,
+                                        false, profile);
+  EXPECT_EQ(profile, future.Get());
   EXPECT_EQ(num_browsers + 1, BrowserList::GetInstance()->size());
   EXPECT_FALSE(ProfilePicker::IsOpen());
 }
 
+IN_PROC_BROWSER_TEST_F(ProfileWindowBrowserTest,
+                       OpenBrowserWindowForProfileBrowserDestroyed) {
+  Profile* profile = browser()->profile();
+  size_t num_browsers = BrowserList::GetInstance()->size();
+
+  base::RunLoop loop;
+  BrowserAddedObserver browser_added_observer(
+      base::BindLambdaForTesting([&loop, this](Browser* browser) {
+        this->CloseBrowserAsynchronously(browser);
+        loop.Quit();
+      }));
+
+  base::test::TestFuture<Profile*> future;
+  profiles::OpenBrowserWindowForProfile(future.GetCallback(), true, false,
+                                        false, profile);
+  base::RunLoop().RunUntilIdle();
+  // `future` is not called because the browser was already destroyed.
+  EXPECT_FALSE(future.IsReady());
+  EXPECT_EQ(num_browsers, BrowserList::GetInstance()->size());
+  EXPECT_FALSE(ProfilePicker::IsOpen());
+}
+
 // TODO(crbug.com/935746): Test is flaky on Win and Linux.
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN)
 #define MAYBE_OpenBrowserWindowForProfileWithSigninRequired \
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn
index b01e70b..74c75f0 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn
@@ -222,9 +222,12 @@
   dest_dir = chromevox_out_dir
   sources = [
     "background/background.html",
+    "earcons/chromevox_loaded.ogg",
+    "earcons/chromevox_loading.ogg",
     "earcons/control.wav",
-    "earcons/selection.wav",
-    "earcons/selection_reverse.wav",
+    "earcons/invalid_keypress.ogg",
+    "earcons/selection.ogg",
+    "earcons/selection_reverse.ogg",
     "earcons/skim.wav",
     "earcons/small_room_2.wav",
     "earcons/static.wav",
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/earcon_engine.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/earcon_engine.js
index 87e9e73..ba450102 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/earcon_engine.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/earcon_engine.js
@@ -56,7 +56,7 @@
     this.defaultPitch = Note.G3;
 
     /** @public {string} The choice of base sound for most controls. */
-    this.controlSound = SoundFile.CONTROL;
+    this.controlSound = WavSoundFile.CONTROL;
 
     /**
      * @public {number} The delay between sounds in the on/off sweep effect,
@@ -129,9 +129,11 @@
     this.currentTrackedEarcon_;
 
     // Initialization: load the base sound data files asynchronously.
-    Object.values(SoundFile)
+    Object.values(WavSoundFile)
         .concat(Object.values(Reverb))
         .forEach(sound => this.loadSound(sound, `${BASE_URL}${sound}.wav`));
+    Object.values(OggSoundFile)
+        .forEach(sound => this.loadSound(sound, `${BASE_URL}${sound}.ogg`));
   }
 
   /**
@@ -365,26 +367,26 @@
 
   /** Play the static sound. */
   onStatic() {
-    this.play(SoundFile.STATIC, {gain: this.staticVolume});
+    this.play(WavSoundFile.STATIC, {gain: this.staticVolume});
   }
 
   /** Play the link sound. */
   onLink() {
-    this.play(SoundFile.STATIC, {gain: this.clickVolume});
+    this.play(WavSoundFile.STATIC, {gain: this.clickVolume});
     this.play(this.controlSound, {pitch: Note.G4});
   }
 
   /** Play the button sound. */
   onButton() {
-    this.play(SoundFile.STATIC, {gain: this.clickVolume});
+    this.play(WavSoundFile.STATIC, {gain: this.clickVolume});
     this.play(this.controlSound);
   }
 
   /** Play the text field sound. */
   onTextField() {
-    this.play(SoundFile.STATIC, {gain: this.clickVolume});
+    this.play(WavSoundFile.STATIC, {gain: this.clickVolume});
     this.play(
-        SoundFile.STATIC,
+        WavSoundFile.STATIC,
         {time: this.baseDelay * 1.5, gain: this.clickVolume * 0.5});
     this.play(this.controlSound, {pitch: Note.B3});
     this.play(
@@ -394,7 +396,7 @@
 
   /** Play the pop up button sound. */
   onPopUpButton() {
-    this.play(SoundFile.STATIC, {gain: this.clickVolume});
+    this.play(WavSoundFile.STATIC, {gain: this.clickVolume});
 
     this.play(this.controlSound);
     this.play(
@@ -407,33 +409,33 @@
 
   /** Play the check on sound. */
   onCheckOn() {
-    this.play(SoundFile.STATIC, {gain: this.clickVolume});
+    this.play(WavSoundFile.STATIC, {gain: this.clickVolume});
     this.play(this.controlSound, {pitch: Note.D3});
     this.play(this.controlSound, {pitch: Note.D4, time: this.baseDelay * 2});
   }
 
   /** Play the check off sound. */
   onCheckOff() {
-    this.play(SoundFile.STATIC, {gain: this.clickVolume});
+    this.play(WavSoundFile.STATIC, {gain: this.clickVolume});
     this.play(this.controlSound, {pitch: Note.D4});
     this.play(this.controlSound, {pitch: Note.D3, time: this.baseDelay * 2});
   }
 
   /** Play the smart sticky mode on sound. */
   onSmartStickyModeOn() {
-    this.play(SoundFile.STATIC, {gain: this.clickVolume * 0.5});
+    this.play(WavSoundFile.STATIC, {gain: this.clickVolume * 0.5});
     this.play(this.controlSound, {pitch: Note.D4});
   }
 
   /** Play the smart sticky mode off sound. */
   onSmartStickyModeOff() {
-    this.play(SoundFile.STATIC, {gain: this.clickVolume * 0.5});
+    this.play(WavSoundFile.STATIC, {gain: this.clickVolume * 0.5});
     this.play(this.controlSound, {pitch: Note.D3});
   }
 
   /** Play the select control sound. */
   onSelect() {
-    this.play(SoundFile.STATIC, {gain: this.clickVolume});
+    this.play(WavSoundFile.STATIC, {gain: this.clickVolume});
     this.play(this.controlSound);
     this.play(this.controlSound, {time: this.baseDelay});
     this.play(this.controlSound, {time: this.baseDelay * 2});
@@ -441,7 +443,7 @@
 
   /** Play the slider sound. */
   onSlider() {
-    this.play(SoundFile.STATIC, {gain: this.clickVolume});
+    this.play(WavSoundFile.STATIC, {gain: this.clickVolume});
     this.play(this.controlSound);
     this.play(
         this.controlSound, {time: this.baseDelay, gain: 0.5, pitch: Note.A3});
@@ -458,21 +460,21 @@
 
   /** Play the skim sound. */
   onSkim() {
-    this.play(SoundFile.SKIM);
+    this.play(WavSoundFile.SKIM);
   }
 
   /** Play the selection sound. */
   onSelection() {
-    this.play(SoundFile.SELECTION);
+    this.play(OggSoundFile.SELECTION);
   }
 
   /** Play the selection reverse sound. */
   onSelectionReverse() {
-    this.play(SoundFile.SELECTION_REVERSE);
+    this.play(OggSoundFile.SELECTION_REVERSE);
   }
 
   onNoPointerAnchor() {
-    this.play(SoundFile.STATIC, {gain: this.clickVolume * 0.2});
+    this.play(WavSoundFile.STATIC, {gain: this.clickVolume * 0.2});
     const freq1 = this.frequencyFor_(Note.A_FLAT4);
     this.generateSinusoidal({
       attack: 0.00001,
@@ -686,7 +688,7 @@
 
   /** Play a wrap sound. */
   onWrap() {
-    this.play(SoundFile.STATIC, {gain: this.clickVolume * 0.3});
+    this.play(WavSoundFile.STATIC, {gain: this.clickVolume * 0.3});
     const freq1 = this.frequencyFor_(this.wrapPitch - 8);
     const freq2 = this.frequencyFor_(this.wrapPitch + 8);
     this.generateSinusoidal({
@@ -711,7 +713,8 @@
       let t = this.progressTime_ - this.context_.currentTime;
       this.progressSources_.push([
         this.progressTime_,
-        this.play(SoundFile.STATIC, {gain: 0.5 * this.progressGain_, time: t}),
+        this.play(
+            WavSoundFile.STATIC, {gain: 0.5 * this.progressGain_, time: t}),
       ]);
       this.progressSources_.push([
         this.progressTime_,
@@ -727,7 +730,8 @@
 
       this.progressSources_.push([
         this.progressTime_,
-        this.play(SoundFile.STATIC, {gain: 0.5 * this.progressGain_, time: t}),
+        this.play(
+            WavSoundFile.STATIC, {gain: 0.5 * this.progressGain_, time: t}),
       ]);
       this.progressSources_.push([
         this.progressTime_,
@@ -862,14 +866,21 @@
 // Local to module.
 
 /* @enum {string} The list of sound data files to load. */
-const SoundFile = {
+const WavSoundFile = {
   CONTROL: 'control',
-  SELECTION: 'selection',
-  SELECTION_REVERSE: 'selection_reverse',
   SKIM: 'skim',
   STATIC: 'static',
 };
 
+/* @enum {string} The list of sound data files to load. */
+const OggSoundFile = {
+  CHROMEVOX_LOADED: 'chromevox_loaded',
+  CHROMEVOX_LOADING: 'chromevox_loading',
+  INVALID_KEYPRESS: 'invalid_keypress',
+  SELECTION: 'selection',
+  SELECTION_REVERSE: 'selection_reverse',
+};
+
 /** @enum {string} The list of reverb data files to load. */
 const Reverb = {
   SMALL_ROOM: 'small_room_2',
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/chromevox_loaded.ogg b/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/chromevox_loaded.ogg
new file mode 100644
index 0000000..6dd753a0
--- /dev/null
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/chromevox_loaded.ogg
Binary files differ
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/chromevox_loading.ogg b/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/chromevox_loading.ogg
new file mode 100644
index 0000000..439bc56
--- /dev/null
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/chromevox_loading.ogg
Binary files differ
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/invalid_keypress.ogg b/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/invalid_keypress.ogg
index 292cefd..43701d8 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/invalid_keypress.ogg
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/invalid_keypress.ogg
Binary files differ
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection.ogg b/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection.ogg
index 95dde34..41cda347 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection.ogg
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection.ogg
Binary files differ
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection.wav b/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection.wav
deleted file mode 100644
index 7be8224..0000000
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection.wav
+++ /dev/null
Binary files differ
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection_reverse.ogg b/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection_reverse.ogg
index 8b04e73..1f03565 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection_reverse.ogg
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection_reverse.ogg
Binary files differ
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection_reverse.wav b/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection_reverse.wav
deleted file mode 100644
index a42b0d9..0000000
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/earcons/selection_reverse.wav
+++ /dev/null
Binary files differ
diff --git a/chrome/browser/resources/chromeos/internet_detail_dialog/BUILD.gn b/chrome/browser/resources/chromeos/internet_detail_dialog/BUILD.gn
index b6e0c29..82c918d 100644
--- a/chrome/browser/resources/chromeos/internet_detail_dialog/BUILD.gn
+++ b/chrome/browser/resources/chromeos/internet_detail_dialog/BUILD.gn
@@ -35,6 +35,7 @@
       "//ash/webui/common/resources:css_wrapper_files",
       "//ash/webui/common/resources:html_wrapper_files",
       "//ash/webui/common/resources:preprocess",
+      "//ui/webui/resources/cr_components/color_change_listener:build_ts",
       "//ui/webui/resources/cr_components/localized_link:build_ts",
       "//ui/webui/resources/cr_elements:build_ts",
       "//ui/webui/resources/mojo:build_ts",
diff --git a/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.html b/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.html
index b601673..503001a 100644
--- a/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.html
+++ b/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.html
@@ -1,5 +1,5 @@
 <style include="cr-page-host-style cr-shared-style network-shared
-    iron-flex">
+    iron-flex cros-color-overrides">
   cr-policy-network-indicator-mojo {
     margin-inline-end: 10px;
   }
diff --git a/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.js b/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.js
index 48d1a870..750db58 100644
--- a/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.js
+++ b/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.js
@@ -17,6 +17,7 @@
 import 'chrome://resources/cr_elements/cr_page_host_style.css.js';
 import 'chrome://resources/cr_elements/icons.html.js';
 import 'chrome://resources/cr_elements/cr_shared_style.css.js';
+import 'chrome://resources/cr_elements/chromeos/cros_color_overrides.css.js';
 import 'chrome://resources/polymer/v3_0/iron-collapse/iron-collapse.js';
 import 'chrome://resources/ash/common/network/apn_list.js';
 import './strings.m.js';
@@ -29,6 +30,7 @@
 import {MojoInterfaceProviderImpl} from 'chrome://resources/ash/common/network/mojo_interface_provider.js';
 import {NetworkListenerBehavior} from 'chrome://resources/ash/common/network/network_listener_behavior.js';
 import {OncMojo} from 'chrome://resources/ash/common/network/onc_mojo.js';
+import {startColorChangeUpdater} from 'chrome://resources/cr_components/color_change_listener/colors_css_updater.js';
 import {ApnProperties, ConfigProperties, CrosNetworkConfigRemote, GlobalPolicy, IPConfigProperties, ManagedProperties, MAX_NUM_CUSTOM_APNS, NetworkStateProperties, ProxySettings, StartConnectResult} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js';
 import {ConnectionStateType, NetworkType, OncSource, PortalState} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/network_types.mojom-webui.js';
 import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
@@ -121,6 +123,19 @@
     },
 
     /**
+     * Return true if Jelly feature flag is enabled.
+     * @private
+     */
+    isJellyEnabled_: {
+      type: Boolean,
+      readOnly: true,
+      value() {
+        return loadTimeData.valueExists('isJellyEnabled') &&
+            loadTimeData.getBoolean('isJellyEnabled');
+      },
+    },
+
+    /**
      * Return true if custom APNs limit is reached.
      * @private
      */
@@ -165,6 +180,14 @@
   attached() {
     this.browserProxy_ = InternetDetailDialogBrowserProxyImpl.getInstance();
     const dialogArgs = this.browserProxy_.getDialogArguments();
+    if (this.isJellyEnabled_) {
+      const link = document.createElement('link');
+      link.rel = 'stylesheet';
+      link.href = 'chrome://theme/colors.css?sets=legacy,sys';
+      document.head.appendChild(link);
+      document.body.classList.add('jelly-enabled');
+      startColorChangeUpdater();
+    }
     let type;
     let name;
     if (dialogArgs) {
diff --git a/chrome/browser/resources/password_manager/BUILD.gn b/chrome/browser/resources/password_manager/BUILD.gn
index 53e609d..c804ca5 100644
--- a/chrome/browser/resources/password_manager/BUILD.gn
+++ b/chrome/browser/resources/password_manager/BUILD.gn
@@ -45,6 +45,7 @@
     "dialogs/edit_password_disclaimer_dialog.ts",
     "dialogs/multi_store_delete_password_dialog.ts",
     "dialogs/move_passwords_dialog.ts",
+    "dialogs/password_preview_item.ts",
     "password_details_card.ts",
     "password_details_section.ts",
     "password_list_item.ts",
diff --git a/chrome/browser/resources/password_manager/dialogs/move_passwords_dialog.html b/chrome/browser/resources/password_manager/dialogs/move_passwords_dialog.html
index 85b3152..2f19062 100644
--- a/chrome/browser/resources/password_manager/dialogs/move_passwords_dialog.html
+++ b/chrome/browser/resources/password_manager/dialogs/move_passwords_dialog.html
@@ -5,18 +5,34 @@
     margin-inline-end: 10px;
     width: 16px;
   }
+
+  #passwords {
+    margin-bottom: 4px;
+    margin-top: 16px;
+  }
 </style>
-<cr-dialog id="dialog" show-on-attach>
+<cr-dialog id="dialog">
   <div slot="title" class="dialog-title">$i18n{movePasswordsTitle}</div>
   <div slot="body">
     <div>$i18n{movePasswordsDescription}</div>
-    <!-- TODO(crbug.com/1420919): Show all passwords  -->
+    <div id="passwords">
+      <dom-repeat items="[[passwords]]">
+        <template>
+          <password-preview-item password-id="[[item.id]]"
+              url="[[getUrl_(item)]]" username="[[item.username]]"
+              password="[[item.password]]" first="[[!index]]"
+              on-change="passwordSelected_">
+          </password-preview-item>
+        </template>
+      </dom-repeat>
+    </div>
   </div>
   <div slot="button-container">
     <cr-button id="cancel" class="cancel-button" on-click="onCancel_">
       $i18n{cancel}
     </cr-button>
-    <cr-button id="move" class="action-button" on-click="onMoveButtonClick_">
+    <cr-button id="move" class="action-button" on-click="onMoveButtonClick_"
+        disabled="[[!selectedPasswordIds_.length]]">
       $i18n{movePasswordsButton}
     </cr-button>
   </div>
diff --git a/chrome/browser/resources/password_manager/dialogs/move_passwords_dialog.ts b/chrome/browser/resources/password_manager/dialogs/move_passwords_dialog.ts
index 5faa3aa..29753a5a 100644
--- a/chrome/browser/resources/password_manager/dialogs/move_passwords_dialog.ts
+++ b/chrome/browser/resources/password_manager/dialogs/move_passwords_dialog.ts
@@ -6,12 +6,14 @@
 import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import '../shared_style.css.js';
 import '../user_utils_mixin.js';
+import './password_preview_item.js';
 
 import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js';
 import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import {assert} from 'chrome://resources/js/assert_ts.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
+import {PasswordManagerImpl} from '../password_manager_proxy.js';
 import {UserUtilMixin} from '../user_utils_mixin.js';
 
 import {getTemplate} from './move_passwords_dialog.html.js';
@@ -46,20 +48,55 @@
         type: Array,
         value: () => [],
       },
+
+      selectedPasswordIds_: {
+        type: Array,
+        valie: () => [],
+      },
     };
   }
 
   passwords: chrome.passwordsPrivate.PasswordUiEntry[];
+  private selectedPasswordIds_: number[];
+
+  override connectedCallback() {
+    super.connectedCallback();
+
+    this.selectedPasswordIds_ = this.passwords.map(item => item.id);
+    PasswordManagerImpl.getInstance()
+        .requestCredentialsDetails(this.selectedPasswordIds_)
+        .then(entries => {
+          this.passwords = entries;
+          this.$.dialog.showModal();
+        })
+        .catch(() => {
+          this.$.dialog.close();
+        });
+  }
 
   private onCancel_() {
-    this.$.dialog.close();
+    this.$.dialog.cancel();
   }
 
   private onMoveButtonClick_() {
     assert(this.isOptedInForAccountStorage);
-    // TODO(crbug.com/1420919): Implement password moving.
+    PasswordManagerImpl.getInstance().movePasswordsToAccount(
+        this.selectedPasswordIds_);
     this.$.dialog.close();
   }
+
+  private getUrl_(password: chrome.passwordsPrivate.PasswordUiEntry): string {
+    assert(password.affiliatedDomains);
+    assert(password.affiliatedDomains.length > 0);
+    return password.affiliatedDomains[0].name;
+  }
+
+  private passwordSelected_() {
+    this.selectedPasswordIds_ =
+        Array.from(this.shadowRoot!.querySelectorAll('password-preview-item'))
+            .filter(item => item.checked)
+            .map(item => item.passwordId);
+  }
 }
 
 declare global {
diff --git a/chrome/browser/resources/password_manager/dialogs/password_preview_item.html b/chrome/browser/resources/password_manager/dialogs/password_preview_item.html
new file mode 100644
index 0000000..3df3cf8
--- /dev/null
+++ b/chrome/browser/resources/password_manager/dialogs/password_preview_item.html
@@ -0,0 +1,79 @@
+<style include="shared-style cr-shared-style">
+  #checkbox {
+    --cr-checkbox-label-padding-start: 8px;
+    --cr-checkbox-size: 14px;
+    --cr-checkbox-border-size: 1px;
+    flex-grow: 0;
+  }
+
+  site-favicon {
+    height: 16px;
+    padding-inline-end: 8px;
+    width: 16px;
+  }
+
+  #container {
+    align-items: center;
+    display: grid;
+    flex-grow: 1;
+    grid-template-columns: auto 125px;
+    width: 100%;
+  }
+
+  .url-username-group {
+    column-gap: 16px;
+    display: grid;
+    grid-template-columns: fit-content(50%) 1fr;
+    padding-inline-end: 16px;
+    width: 100%;
+  }
+
+  #website {
+    color: var(--cr-primary-text-color);
+  }
+
+  #password {
+    background-color: transparent;
+    border: none;
+  }
+
+  #password:disabled {
+    flex: none;
+    font-family: inherit;
+    margin-inline-start: auto;
+    text-overflow: clip;
+    width: 50px;
+  }
+
+  cr-icon-button {
+    --cr-icon-button-margin-start: 8px;
+  }
+
+</style>
+<div class="flex-centered" focus-row-container>
+  <cr-checkbox id="checkbox" checked="{{checked}}">
+  </cr-checkbox>
+  <div id="container" class$="[[getElementClass_(first)]]">
+    <div class="flex-centered">
+      <site-favicon domain="[[url]]" aria-hidden="true">
+      </site-favicon>
+      <div class="url-username-group">
+        <div id="website" class="text-elide">[[url]]</div>
+        <div id="username" class="text-elide">[[username]]</div>
+      </div>
+    </div>
+    <div class="flex-centered">
+      <input id="password" readonly class="text-elide"
+          type="[[getPasswordInputType(isPasswordVisible)]]"
+          disabled$="[[!isPasswordVisible]]"
+          value="[[getPasswordValue_(isPasswordVisible, password)]]"
+          focus-row-control focus-type="passwordField">
+      <cr-icon-button id="showPasswordButton"
+          title="[[getShowHideButtonLabel(isPasswordVisible)]]"
+          class$="[[getShowHideButtonIconClass(isPasswordVisible)]]"
+          on-click="onShowHidePasswordButtonClick"
+          focus-row-control focus-type="showPassword">
+      </cr-icon-button>
+    </div>
+  </div>
+</div>
diff --git a/chrome/browser/resources/password_manager/dialogs/password_preview_item.ts b/chrome/browser/resources/password_manager/dialogs/password_preview_item.ts
new file mode 100644
index 0000000..c75b99a2
--- /dev/null
+++ b/chrome/browser/resources/password_manager/dialogs/password_preview_item.ts
@@ -0,0 +1,82 @@
+// 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.
+
+/**
+ * @fileoverview PasswordPreviewItem represents one row in a list of passwords.
+ * It needs to be its own component because FocusRowBehavior provides good a11y.
+ */
+
+import 'chrome://resources/cr_elements/cr_icons.css.js';
+import 'chrome://resources/cr_elements/cr_shared_style.css.js';
+import '../site_favicon.js';
+import '../shared_style.css.js';
+
+import {CrCheckboxElement} from 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.js';
+import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {ShowPasswordMixin} from '../show_password_mixin.js';
+
+import {getTemplate} from './password_preview_item.html.js';
+
+export interface PasswordPreviewItemElement {
+  $: {
+    checkbox: CrCheckboxElement,
+    website: HTMLElement,
+    username: HTMLElement,
+    password: HTMLInputElement,
+    showPasswordButton: CrIconButtonElement,
+  };
+}
+
+const PasswordPreviewItemElementBase = ShowPasswordMixin(PolymerElement);
+
+export class PasswordPreviewItemElement extends PasswordPreviewItemElementBase {
+  static get is() {
+    return 'password-preview-item';
+  }
+
+  static get template() {
+    return getTemplate();
+  }
+
+  static get properties() {
+    return {
+      passwordId: Number,
+      url: String,
+      username: String,
+      password: String,
+      first: Boolean,
+
+      checked: {
+        type: Boolean,
+        value: true,
+      },
+    };
+  }
+
+  passwordId: number;
+  url: string;
+  username: string;
+  password: string;
+  first: boolean;
+  checked: boolean;
+
+  private getElementClass_(): string {
+    return this.first ? '' : 'hr';
+  }
+
+  private getPasswordValue_(): string {
+    return this.isPasswordVisible ? this.password : ' '.repeat(10);
+  }
+}
+
+declare global {
+  interface HTMLElementTagNameMap {
+    'password-preview-item': PasswordPreviewItemElement;
+  }
+}
+
+customElements.define(
+    PasswordPreviewItemElement.is, PasswordPreviewItemElement);
diff --git a/chrome/browser/resources/password_manager/password_manager_proxy.ts b/chrome/browser/resources/password_manager/password_manager_proxy.ts
index dd2bf1ee..f3a16ed 100644
--- a/chrome/browser/resources/password_manager/password_manager_proxy.ts
+++ b/chrome/browser/resources/password_manager/password_manager_proxy.ts
@@ -308,6 +308,12 @@
    * @return A promise that resolves to whether the account store is default.
    */
   isAccountStoreDefault(): Promise<boolean>;
+
+  /**
+   * Moves a list of passwords from the device to the account
+   * @param ids The ids for the password entries being moved.
+   */
+  movePasswordsToAccount(ids: number[]): void;
 }
 
 /**
@@ -507,6 +513,10 @@
     return chrome.passwordsPrivate.isAccountStoreDefault();
   }
 
+  movePasswordsToAccount(ids: number[]) {
+    chrome.passwordsPrivate.movePasswordsToAccount(ids);
+  }
+
   static getInstance(): PasswordManagerProxy {
     return instance || (instance = new PasswordManagerImpl());
   }
diff --git a/chrome/browser/resources/password_manager/shared_style.css b/chrome/browser/resources/password_manager/shared_style.css
index 23289d4..e076fb0 100644
--- a/chrome/browser/resources/password_manager/shared_style.css
+++ b/chrome/browser/resources/password_manager/shared_style.css
@@ -71,3 +71,9 @@
   text-overflow: ellipsis;
   white-space: nowrap;
 }
+
+.text-elide {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
diff --git a/chrome/browser/resources/privacy_sandbox/BUILD.gn b/chrome/browser/resources/privacy_sandbox/BUILD.gn
index 987bd2f..d03c15d 100644
--- a/chrome/browser/resources/privacy_sandbox/BUILD.gn
+++ b/chrome/browser/resources/privacy_sandbox/BUILD.gn
@@ -14,6 +14,7 @@
     "privacy_sandbox_dialog.html",
     "privacy_sandbox_combined_dialog.html",
     "privacy_sandbox_notice_dialog.html",
+    "privacy_sandbox_notice_restricted_dialog.html",
     "images/privacy_sandbox_confirmation_banner.svg",
     "images/privacy_sandbox_confirmation_banner_dark.svg",
 
@@ -28,6 +29,7 @@
     "privacy_sandbox_dialog_app.ts",
     "privacy_sandbox_combined_dialog_app.ts",
     "privacy_sandbox_notice_dialog_app.ts",
+    "privacy_sandbox_notice_restricted_dialog_app.ts",
     "privacy_sandbox_dialog_consent_step.ts",
     "privacy_sandbox_dialog_notice_step.ts",
     "privacy_sandbox_dialog_learn_more.ts",
diff --git a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog.html b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog.html
new file mode 100644
index 0000000..3bab63e
--- /dev/null
+++ b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html dir="$i18n{textdirection}" lang="$i18n{language}">
+<head>
+  <meta charset="utf-8">
+  <!-- TODO(b/277180532): add actual title, dialog structure, etc. -->
+  <script type="module"
+    src="privacy_sandbox_notice_restricted_dialog_app.js"></script>
+</head>
+<body>
+  <privacy-sandbox-notice-restricted-dialog-app>
+  </privacy-sandbox-notice-restricted-dialog-app>
+</body>
+</html>
diff --git a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog_app.html b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog_app.html
new file mode 100644
index 0000000..b399729
--- /dev/null
+++ b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog_app.html
@@ -0,0 +1,5 @@
+<!-- TODO(b/277180532): add actual title, dialog structure, etc. -->
+<style include="cr-shared-style shared-style"></style>
+<div fill-content role="main">
+  $i18n{m1NoticeRestrictedDescription1}
+</div>
diff --git a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog_app.ts b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog_app.ts
new file mode 100644
index 0000000..3afa501
--- /dev/null
+++ b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog_app.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 'chrome://resources/cr_elements/cr_shared_style.css.js';
+import './shared_style.css.js';
+
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {PrivacySandboxDialogResizeMixin} from './privacy_sandbox_dialog_resize_mixin.js';
+import {getTemplate} from './privacy_sandbox_notice_restricted_dialog_app.html.js';
+
+const PrivacySandboxNoticeRestrictedDialogAppElementBase =
+    PrivacySandboxDialogResizeMixin(PolymerElement);
+
+export class PrivacySandboxNoticeRestrictedDialogAppElement extends
+    PrivacySandboxNoticeRestrictedDialogAppElementBase {
+  static get is() {
+    return 'privacy-sandbox-notice-restricted-dialog-app';
+  }
+
+  static get template() {
+    return getTemplate();
+  }
+
+  override ready() {
+    super.ready();
+
+    // TODO(b/277180532): fire the appropriate events, add more structure, etc.
+    this.resizeAndShowNativeDialog();
+  }
+}
+
+
+declare global {
+  interface HTMLElementTagNameMap {
+    'privacy-sandbox-notice-restricted-dialog-app':
+        PrivacySandboxNoticeRestrictedDialogAppElement;
+  }
+}
+
+customElements.define(
+    PrivacySandboxNoticeRestrictedDialogAppElement.is,
+    PrivacySandboxNoticeRestrictedDialogAppElement);
diff --git a/chrome/browser/resources/settings/BUILD.gn b/chrome/browser/resources/settings/BUILD.gn
index 9122fb8..69c8e93e 100644
--- a/chrome/browser/resources/settings/BUILD.gn
+++ b/chrome/browser/resources/settings/BUILD.gn
@@ -265,6 +265,9 @@
   if (is_chromeos) {
     web_component_files += [ "controls/password_prompt_dialog.ts" ]
   }
+  if (is_chrome_branded) {
+    web_component_files += [ "get_most_chrome_page/get_most_chrome_page.ts" ]
+  }
 
   # -----------------web_component_files end ----------------------------------
 
diff --git a/chrome/browser/resources/settings/about_page/about_page.ts b/chrome/browser/resources/settings/about_page/about_page.ts
index 4608d09d..52c24ff3 100644
--- a/chrome/browser/resources/settings/about_page/about_page.ts
+++ b/chrome/browser/resources/settings/about_page/about_page.ts
@@ -31,6 +31,11 @@
 
 import {loadTimeData} from '../i18n_setup.js';
 import {RelaunchMixin, RestartType} from '../relaunch_mixin.js';
+// <if expr="_google_chrome">
+import {routes} from '../route.js';
+import {Router} from '../router.js';
+
+// </if>
 
 import {getTemplate} from './about_page.html.js';
 import {AboutPageBrowserProxy, AboutPageBrowserProxyImpl, UpdateStatus, UpdateStatusChangedEvent} from './about_page_browser_proxy.js';
@@ -40,6 +45,7 @@
 // </if>
 // clang-format on
 
+
 const SettingsAboutPageElementBase =
     RelaunchMixin(WebUiListenerMixin(I18nMixin(PolymerElement)));
 
@@ -82,7 +88,8 @@
       showGetTheMostOutOfChromeSection_: {
         type: Boolean,
         value() {
-          return loadTimeData.getBoolean('showGetTheMostOutOfChromeSection');
+          return loadTimeData.getBoolean('showGetTheMostOutOfChromeSection') &&
+              !loadTimeData.getBoolean('isGuest');
         },
       },
       // </if>
@@ -342,8 +349,8 @@
     this.aboutBrowserProxy_.openFeedbackDialog();
   }
 
-  private onGetTheMostOutOfChromeClick_() {
-    // TODO(crbug.com/1423278): implement.
+  private onGetTheMostOutOfChromeTap_() {
+    Router.getInstance().navigateTo(routes.GET_MOST_CHROME);
   }
   // </if>
 
diff --git a/chrome/browser/resources/settings/basic_page/basic_page.html b/chrome/browser/resources/settings/basic_page/basic_page.html
index 55ad4f0..2c9d775 100644
--- a/chrome/browser/resources/settings/basic_page/basic_page.html
+++ b/chrome/browser/resources/settings/basic_page/basic_page.html
@@ -205,6 +205,16 @@
                 <settings-reset-page prefs="{{prefs}}"></settings-reset-page>
               </settings-section>
             </template>
+<if expr="_google_chrome">
+            <template is="dom-if"
+                if="[[showGetMostChrome_(pageVisibility.getMostChrome)]]"
+                restamp>
+              <settings-section page-title="$i18n{getTheMostOutOfChrome}"
+                  section="getMostChrome">
+                <settings-get-most-chrome-page></settings-get-most-chrome-page>
+              </settings-section>
+            </template>
+</if>
           </div>
         </template>
       </settings-idle-load>
diff --git a/chrome/browser/resources/settings/basic_page/basic_page.ts b/chrome/browser/resources/settings/basic_page/basic_page.ts
index 000a5c0..bea931e 100644
--- a/chrome/browser/resources/settings/basic_page/basic_page.ts
+++ b/chrome/browser/resources/settings/basic_page/basic_page.ts
@@ -395,6 +395,11 @@
   }
 
   // <if expr="_google_chrome">
+  private showGetMostChrome_(visibility?: boolean): boolean {
+    return visibility !== false &&
+        loadTimeData.getBoolean('showGetTheMostOutOfChromeSection');
+  }
+
   private onSendHighEfficiencyFeedbackClick_(e: Event) {
     e.stopPropagation();
     this.performanceBrowserProxy_.openHighEfficiencyFeedbackDialog();
diff --git a/chrome/browser/resources/settings/get_most_chrome_page/get_most_chrome_page.html b/chrome/browser/resources/settings/get_most_chrome_page/get_most_chrome_page.html
new file mode 100644
index 0000000..7c89b54
--- /dev/null
+++ b/chrome/browser/resources/settings/get_most_chrome_page/get_most_chrome_page.html
@@ -0,0 +1 @@
+<div></div>
diff --git a/chrome/browser/resources/settings/get_most_chrome_page/get_most_chrome_page.ts b/chrome/browser/resources/settings/get_most_chrome_page/get_most_chrome_page.ts
new file mode 100644
index 0000000..029614ab
--- /dev/null
+++ b/chrome/browser/resources/settings/get_most_chrome_page/get_most_chrome_page.ts
@@ -0,0 +1,32 @@
+// 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.
+
+/**
+ * @fileoverview
+ * 'settings-get-most-chrome-page' is the settings page information about how
+ * to get the most out of Chrome.
+ */
+
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {getTemplate} from './get_most_chrome_page.html.js';
+
+export class SettingsGetMostChromePageElement extends PolymerElement {
+  static get is() {
+    return 'settings-get-most-chrome-page';
+  }
+
+  static get template() {
+    return getTemplate();
+  }
+}
+
+declare global {
+  interface HTMLElementTagNameMap {
+    'settings-get-most-chrome-page': SettingsGetMostChromePageElement;
+  }
+}
+
+customElements.define(
+    SettingsGetMostChromePageElement.is, SettingsGetMostChromePageElement);
diff --git a/chrome/browser/resources/settings/lazy_load.ts b/chrome/browser/resources/settings/lazy_load.ts
index 4fc7d32..04d16b8 100644
--- a/chrome/browser/resources/settings/lazy_load.ts
+++ b/chrome/browser/resources/settings/lazy_load.ts
@@ -66,6 +66,9 @@
 // Sections
 import './a11y_page/a11y_page.js';
 import './downloads_page/downloads_page.js';
+// <if expr="_google_chrome">
+import './get_most_chrome_page/get_most_chrome_page.js';
+// </if>
 // <if expr="not chromeos_ash">
 import './languages_page/languages_page.js';
 import './languages_page/spell_check_page.js';
@@ -138,6 +141,9 @@
 export {SettingsSliderElement} from './controls/settings_slider.js';
 export {DownloadsBrowserProxy, DownloadsBrowserProxyImpl} from './downloads_page/downloads_browser_proxy.js';
 export {SettingsDownloadsPageElement} from './downloads_page/downloads_page.js';
+// <if expr="_google_chrome">
+export {SettingsGetMostChromePageElement} from './get_most_chrome_page/get_most_chrome_page.js';
+// </if>
 // <if expr="_google_chrome and is_win">
 export {IncompatibleApplicationItemElement} from './incompatible_applications_page/incompatible_application_item.js';
 export {ActionTypes, IncompatibleApplication, IncompatibleApplicationsBrowserProxy, IncompatibleApplicationsBrowserProxyImpl} from './incompatible_applications_page/incompatible_applications_browser_proxy.js';
diff --git a/chrome/browser/resources/settings/page_visibility.ts b/chrome/browser/resources/settings/page_visibility.ts
index c4829c17..0234474 100644
--- a/chrome/browser/resources/settings/page_visibility.ts
+++ b/chrome/browser/resources/settings/page_visibility.ts
@@ -15,6 +15,7 @@
   defaultBrowser?: boolean;
   downloads?: boolean;
   extensions?: boolean;
+  getMostChrome?: boolean;
   languages?: boolean;
   onStartup?: boolean;
   people?: boolean;
@@ -55,6 +56,7 @@
     defaultBrowser: false,
     downloads: false,
     extensions: false,
+    getMostChrome: false,
     languages: false,
     onStartup: false,
     people: false,
@@ -87,6 +89,7 @@
     downloads: true,
     a11y: true,
     extensions: false,
+    getMostChrome: false,
     languages: true,
     performance: false,
   };
diff --git a/chrome/browser/resources/settings/route.ts b/chrome/browser/resources/settings/route.ts
index 13971aa..7b63dfed 100644
--- a/chrome/browser/resources/settings/route.ts
+++ b/chrome/browser/resources/settings/route.ts
@@ -262,6 +262,14 @@
           '/performance', 'performance',
           loadTimeData.getString('performancePageTitle'));
     }
+
+    // <if expr="_google_chrome">
+    if (visibility.getMostChrome !== false) {
+      r.GET_MOST_CHROME = r.ADVANCED.createSection(
+          '/getMostChrome', 'getMostChrome',
+          loadTimeData.getString('getTheMostOutOfChrome'));
+    }
+    // </if>
   }
   return r as unknown as SettingsRoutes;
 }
diff --git a/chrome/browser/resources/settings/router.ts b/chrome/browser/resources/settings/router.ts
index 5656181..c24a1ac 100644
--- a/chrome/browser/resources/settings/router.ts
+++ b/chrome/browser/resources/settings/router.ts
@@ -29,6 +29,9 @@
   DOWNLOADS: Route;
   EDIT_DICTIONARY: Route;
   FONTS: Route;
+  // <if expr="_google_chrome">
+  GET_MOST_CHROME: Route;
+  // </if>
   IMPORT_DATA: Route;
   INCOMPATIBLE_APPLICATIONS: Route;
   LANGUAGES: Route;
diff --git a/chrome/browser/resources/side_panel/read_anything/read_anything.html b/chrome/browser/resources/side_panel/read_anything/read_anything.html
index 02d87e4..f446a00 100644
--- a/chrome/browser/resources/side_panel/read_anything/read_anything.html
+++ b/chrome/browser/resources/side_panel/read_anything/read_anything.html
@@ -18,7 +18,6 @@
     body {
       overflow-wrap: break-word;
       overflow-x: hidden;
-      overflow-y: scroll;
     }
   </style>
 </head>
diff --git a/chrome/browser/safe_browsing/chrome_user_population_helper.cc b/chrome/browser/safe_browsing/chrome_user_population_helper.cc
index c29d416..b1af691 100644
--- a/chrome/browser/safe_browsing/chrome_user_population_helper.cc
+++ b/chrome/browser/safe_browsing/chrome_user_population_helper.cc
@@ -4,9 +4,11 @@
 
 #include "chrome/browser/safe_browsing/chrome_user_population_helper.h"
 
+#include "base/metrics/field_trial.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/no_destructor.h"
 #include "build/chromeos_buildflags.h"
+#include "chrome/browser/browser_features.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/policy/chrome_browser_policy_connector.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -114,6 +116,43 @@
   return population;
 }
 
+ChromeUserPopulation GetUserPopulationForProfileWithCookieTheftExperiments(
+    Profile* profile) {
+  ChromeUserPopulation population = GetUserPopulationForProfile(profile);
+
+  if (population.user_population() ==
+      ChromeUserPopulation::ENHANCED_PROTECTION) {
+    static const base::NoDestructor<std::vector<const base::Feature*>>
+        kCookieTheftExperiments({
+#if BUILDFLAG(IS_WIN)
+          &features::kLockProfileCookieDatabase
+#endif
+        });
+
+    GetExperimentStatus(*kCookieTheftExperiments, &population);
+  }
+
+  return population;
+}
+
+void GetExperimentStatus(const std::vector<const base::Feature*>& experiments,
+                         ChromeUserPopulation* population) {
+  for (const base::Feature* feature : experiments) {
+    base::FieldTrial* field_trial = base::FeatureList::GetFieldTrial(*feature);
+    if (!field_trial) {
+      continue;
+    }
+    const std::string& trial = field_trial->trial_name();
+    const std::string& group = field_trial->GetGroupNameWithoutActivation();
+    bool is_experimental = group.find("Enabled") != std::string::npos ||
+                           group.find("Control") != std::string::npos;
+    bool is_preperiod = group.find("Preperiod") != std::string::npos;
+    if (is_experimental && !is_preperiod) {
+      population->add_finch_active_groups(trial + "." + group);
+    }
+  }
+}
+
 ChromeUserPopulation::PageLoadToken GetPageLoadTokenForURL(Profile* profile,
                                                            GURL url) {
   if (!profile) {
diff --git a/chrome/browser/safe_browsing/chrome_user_population_helper.h b/chrome/browser/safe_browsing/chrome_user_population_helper.h
index 53e6b95e..1953bd0 100644
--- a/chrome/browser/safe_browsing/chrome_user_population_helper.h
+++ b/chrome/browser/safe_browsing/chrome_user_population_helper.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_SAFE_BROWSING_CHROME_USER_POPULATION_HELPER_H_
 #define CHROME_BROWSER_SAFE_BROWSING_CHROME_USER_POPULATION_HELPER_H_
 
+#include "base/feature_list.h"
 #include "chrome/browser/profiles/profile.h"
 #include "components/safe_browsing/core/common/proto/csd.pb.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -15,6 +16,17 @@
 // given |profile|.
 ChromeUserPopulation GetUserPopulationForProfile(Profile* profile);
 
+// A convenience function that creates a ChromeUserPopulation proto for the
+// given |profile|. This is used by real-time URL lookups and download pings to
+// sometimes add telemetry about running experiments.
+ChromeUserPopulation GetUserPopulationForProfileWithCookieTheftExperiments(
+    Profile* profile);
+
+// Get the status of each experiment in `experiments` and put it in the
+// `finch_active_groups` field of `population`.
+void GetExperimentStatus(const std::vector<const base::Feature*>& experiments,
+                         ChromeUserPopulation* population);
+
 // These values are persisted to logs. Entries should not be renumbered and
 // numeric values should never be reused.
 enum class NoCachedPopulationReason {
diff --git a/chrome/browser/safe_browsing/chrome_user_population_helper_unittest.cc b/chrome/browser/safe_browsing/chrome_user_population_helper_unittest.cc
index 9810f9b..abd21378 100644
--- a/chrome/browser/safe_browsing/chrome_user_population_helper_unittest.cc
+++ b/chrome/browser/safe_browsing/chrome_user_population_helper_unittest.cc
@@ -4,6 +4,9 @@
 
 #include "chrome/browser/safe_browsing/chrome_user_population_helper.h"
 
+#include "base/feature_list.h"
+#include "base/metrics/field_trial.h"
+#include "base/test/scoped_feature_list.h"
 #include "chrome/browser/safe_browsing/advanced_protection_status_manager.h"
 #include "chrome/browser/safe_browsing/advanced_protection_status_manager_factory.h"
 #include "chrome/browser/safe_browsing/verdict_cache_manager_factory.h"
@@ -21,11 +24,16 @@
 #include "components/version_info/version_info.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/protobuf/src/google/protobuf/repeated_ptr_field.h"
 
 namespace safe_browsing {
 
 namespace {
 
+BASE_FEATURE(kTestCookieTheftFeature,
+             "TestCookieTheftFeature",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 std::unique_ptr<KeyedService> CreateTestSyncService(
     content::BrowserContext* context) {
   return std::make_unique<syncer::TestSyncService>();
@@ -210,4 +218,84 @@
   EXPECT_TRUE(token.has_token_value());
 }
 
+TEST(GetExperimentStatusTest, HasEnabled) {
+  base::FieldTrialList::CreateFieldTrial("TestCookieTheftFeature", "Enabled");
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitFromCommandLine(
+      "TestCookieTheftFeature<TestCookieTheftFeature.Enabled", "");
+
+  ChromeUserPopulation population;
+  GetExperimentStatus({&kTestCookieTheftFeature}, &population);
+
+  ASSERT_EQ(population.finch_active_groups_size(), 1);
+  EXPECT_EQ(population.finch_active_groups(0),
+            "TestCookieTheftFeature.Enabled");
+}
+
+TEST(GetExperimentStatusTest, HasControl) {
+  base::FieldTrialList::CreateFieldTrial("TestCookieTheftFeature", "Control");
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitFromCommandLine(
+      "TestCookieTheftFeature<TestCookieTheftFeature.Control", "");
+
+  ChromeUserPopulation population;
+  GetExperimentStatus({&kTestCookieTheftFeature}, &population);
+
+  ASSERT_EQ(population.finch_active_groups_size(), 1);
+  EXPECT_EQ(population.finch_active_groups(0),
+            "TestCookieTheftFeature.Control");
+}
+
+TEST(GetExperimentStatusTest, OmitsDefault) {
+  base::FieldTrialList::CreateFieldTrial("TestCookieTheftFeature", "Default");
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitFromCommandLine(
+      "TestCookieTheftFeature<TestCookieTheftFeature.Default", "");
+
+  ChromeUserPopulation population;
+  GetExperimentStatus({&kTestCookieTheftFeature}, &population);
+
+  ASSERT_EQ(population.finch_active_groups_size(), 0);
+}
+
+#if BUILDFLAG(IS_WIN)
+TEST(GetUserPopulationForProfileWithCookieTheftExperiments,
+     PopulatesExperimentsForEsb) {
+  content::BrowserTaskEnvironment task_environment;
+  base::FieldTrialList::CreateFieldTrial("LockProfileCookieDatabase",
+                                         "Enabled");
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitFromCommandLine(
+      "LockProfileCookieDatabase<LockProfileCookieDatabase.Enabled", "");
+
+  TestingProfile profile;
+  SetSafeBrowsingState(profile.GetPrefs(),
+                       SafeBrowsingState::ENHANCED_PROTECTION);
+  ChromeUserPopulation population =
+      GetUserPopulationForProfileWithCookieTheftExperiments(&profile);
+
+  EXPECT_TRUE(base::Contains(population.finch_active_groups(),
+                             "LockProfileCookieDatabase.Enabled"));
+}
+
+TEST(GetUserPopulationForProfileWithCookieTheftExperiments,
+     DoesNotPopulateExperimentsForSsb) {
+  content::BrowserTaskEnvironment task_environment;
+  base::FieldTrialList::CreateFieldTrial("LockProfileCookieDatabase",
+                                         "Enabled");
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitFromCommandLine(
+      "LockProfileCookieDatabase<LockProfileCookieDatabase.Enabled", "");
+
+  TestingProfile profile;
+  SetSafeBrowsingState(profile.GetPrefs(),
+                       SafeBrowsingState::STANDARD_PROTECTION);
+  ChromeUserPopulation population =
+      GetUserPopulationForProfileWithCookieTheftExperiments(&profile);
+
+  EXPECT_FALSE(base::Contains(population.finch_active_groups(),
+                              "LockProfileCookieDatabase.Enabled"));
+}
+#endif
+
 }  // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/download_protection/download_request_maker.cc b/chrome/browser/safe_browsing/download_protection/download_request_maker.cc
index d585d97..034f7e9a 100644
--- a/chrome/browser/safe_browsing/download_protection/download_request_maker.cc
+++ b/chrome/browser/safe_browsing/download_protection/download_request_maker.cc
@@ -165,7 +165,8 @@
       profile && AdvancedProtectionStatusManagerFactory::GetForProfile(profile)
                      ->IsUnderAdvancedProtection();
 
-  *request_->mutable_population() = GetUserPopulationForProfile(profile);
+  *request_->mutable_population() =
+      GetUserPopulationForProfileWithCookieTheftExperiments(profile);
   if (base::FeatureList::IsEnabled(kNestedArchives)) {
     request_->mutable_population()->add_finch_active_groups(
         "SafeBrowsingArchiveImprovements.Enabled");
diff --git a/chrome/browser/safe_browsing/url_lookup_service_factory.cc b/chrome/browser/safe_browsing/url_lookup_service_factory.cc
index 8fea58d6..8edc3c9 100644
--- a/chrome/browser/safe_browsing/url_lookup_service_factory.cc
+++ b/chrome/browser/safe_browsing/url_lookup_service_factory.cc
@@ -74,7 +74,9 @@
   return new RealTimeUrlLookupService(
       network::SharedURLLoaderFactory::Create(std::move(url_loader_factory)),
       VerdictCacheManagerFactory::GetForProfile(profile),
-      base::BindRepeating(&safe_browsing::GetUserPopulationForProfile, profile),
+      base::BindRepeating(
+          &safe_browsing::GetUserPopulationForProfileWithCookieTheftExperiments,
+          profile),
       profile->GetPrefs(),
       std::make_unique<SafeBrowsingPrimaryAccountTokenFetcher>(
           IdentityManagerFactory::GetForProfile(profile)),
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/ChromeProvidedSharingOptionsProviderBase.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/ChromeProvidedSharingOptionsProviderBase.java
index 670f430..773c6db4 100644
--- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/ChromeProvidedSharingOptionsProviderBase.java
+++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/ChromeProvidedSharingOptionsProviderBase.java
@@ -9,6 +9,7 @@
 import android.content.ClipboardManager;
 import android.content.Context;
 import android.net.Uri;
+import android.text.TextUtils;
 import android.view.View;
 
 import androidx.annotation.Nullable;
@@ -277,7 +278,7 @@
     }
 
     private void maybeAddQrCodeFirstPartyOption() {
-        if (!mIsIncognito) {
+        if (!mIsIncognito && !TextUtils.isEmpty(mUrl)) {
             mOrderedFirstPartyOptions.add(createQrCodeFirstPartyOption());
         }
     }
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetController.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetController.java
index c7d8a68..b1b9954 100644
--- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetController.java
+++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetController.java
@@ -123,11 +123,12 @@
 
         if (showCustomActions) {
             boolean isInMultiWindow = ApiCompatibilityUtils.isInMultiWindowMode(activity);
-            var actionProvider = new AndroidCustomActionProvider(
-                    params.getWindow().getActivity().get(), params.getWindow(), mTabProvider,
-                    mController, params, mPrintCallback, isIncognito, this,
-                    TrackerFactory.getTrackerForProfile(profile), params.getUrl(), profile,
-                    chromeShareExtras, isInMultiWindow, mLinkToTextCoordinator);
+            var actionProvider =
+                    new AndroidCustomActionProvider(params.getWindow().getActivity().get(),
+                            params.getWindow(), mTabProvider, mController, params, mPrintCallback,
+                            isIncognito, this, TrackerFactory.getTrackerForProfile(profile),
+                            getUrlToShare(params, chromeShareExtras), profile, chromeShareExtras,
+                            isInMultiWindow, mLinkToTextCoordinator);
             if (actionProvider.getCustomActions().size() > 0
                     || actionProvider.getModifyShareAction() != null) {
                 provider = actionProvider;
@@ -142,9 +143,10 @@
         // Update the image being shared into ShareParams's url based on the information from
         // chromeShareExtras.
         if (chromeShareExtras.isImage()) {
-            String imageUrlToShare = getImageUrlToShare(params, chromeShareExtras);
+            String imageUrlToShare = getUrlToShare(params, chromeShareExtras);
             params.setUrl(imageUrlToShare);
         }
+
         if (!isLinkSharing(params, chromeShareExtras)) {
             ShareHelper.shareWithSystemShareSheetUi(
                     params, profile, chromeShareExtras.saveLastUsed(), provider);
@@ -221,7 +223,7 @@
                 || contents.contains(ContentType.LINK_PAGE_NOT_VISIBLE);
     }
 
-    private static String getImageUrlToShare(
+    private static String getUrlToShare(
             ShareParams shareParams, ChromeShareExtras chromeShareExtras) {
         if (!TextUtils.isEmpty(shareParams.getUrl())) {
             return shareParams.getUrl();
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/qrcode/QrCodeCoordinator.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/qrcode/QrCodeCoordinator.java
index 5973e0a..4db32ae 100644
--- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/qrcode/QrCodeCoordinator.java
+++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/qrcode/QrCodeCoordinator.java
@@ -6,6 +6,7 @@
 
 import android.app.Activity;
 import android.app.FragmentManager;
+import android.text.TextUtils;
 
 import org.chromium.ui.base.WindowAndroid;
 
@@ -23,6 +24,7 @@
      * @param windowAndroid the WindowAndroid to access system permissions.
      */
     public QrCodeCoordinator(Activity activity, String url, WindowAndroid windowAndroid) {
+        assert !TextUtils.isEmpty(url) : "URL for QR code is empty.";
         mDialog = QrCodeDialog.newInstance(url, windowAndroid);
 
         mFragmentManager = activity.getFragmentManager();
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetControllerUnitTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetControllerUnitTest.java
index bc0e0d3..5541627 100644
--- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetControllerUnitTest.java
+++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetControllerUnitTest.java
@@ -27,6 +27,7 @@
 import android.text.TextUtils;
 
 import androidx.annotation.Nullable;
+import androidx.annotation.StringRes;
 import androidx.core.os.BuildCompat;
 import androidx.lifecycle.Lifecycle.State;
 import androidx.test.ext.junit.rules.ActivityScenarioRule;
@@ -39,6 +40,7 @@
 import org.junit.rules.TestRule;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 import org.robolectric.Shadows;
@@ -63,10 +65,9 @@
 import org.chromium.chrome.browser.share.ChromeShareExtras;
 import org.chromium.chrome.browser.share.ChromeShareExtras.DetailedContentType;
 import org.chromium.chrome.browser.share.ShareHelper;
-import org.chromium.chrome.browser.share.android_share_sheet.AndroidShareSheetControllerUnitTest.ShadowBuildCompatForU;
-import org.chromium.chrome.browser.share.android_share_sheet.AndroidShareSheetControllerUnitTest.ShadowChooserActionHelper;
 import org.chromium.chrome.browser.share.android_share_sheet.AndroidShareSheetControllerUnitTest.ShadowShareImageFileUtils;
 import org.chromium.chrome.browser.share.link_to_text.LinkToTextCoordinator;
+import org.chromium.chrome.browser.share.qrcode.QrCodeDialog;
 import org.chromium.chrome.browser.share.send_tab_to_self.SendTabToSelfAndroidBridgeJni;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
@@ -107,11 +108,6 @@
     private static final String KEY_CHOOSER_ACTION_ACTION = "action";
     private static final String SELECTOR_FOR_LINK_TO_TEXT = "selector";
 
-    private static final String USER_ACTION_SEND_TAB_TO_SELF_SELECTED =
-            "SharingHubAndroid.SendTabToSelfSelected";
-    private static final String USER_ACTION_QR_CODE_SELECTED = "SharingHubAndroid.QRCodeSelected";
-    private static final String USER_ACTION_PRINT_SELECTED = "SharingHubAndroid.PrintSelected";
-
     private static final Uri TEST_WEB_FAVICON_PREVIEW_URI =
             Uri.parse("content://test.web.favicon.preview");
     private static final Uri TEST_FALLBACK_FAVICON_PREVIEW_URI =
@@ -193,6 +189,7 @@
     @After
     public void tearDown() {
         ShadowLinkToTextCoordinator.setForceToFail(null);
+        ShadowQrCodeDialog.sLastUrl = null;
         mWindow.destroy();
         TrackerFactory.setTrackerForTests(null);
     }
@@ -258,27 +255,7 @@
                 () -> mTab, () -> mTabModelSelector, () -> mProfile, mPrintCallback::notifyCalled);
 
         Intent intent = Shadows.shadowOf((Activity) mActivity).peekNextStartedActivity();
-        Parcelable[] actions = intent.getParcelableArrayExtra(INTENT_EXTRA_CHOOSER_CUSTOM_ACTIONS);
-
-        Assert.assertTrue("More than one action is provided.", actions.length > 0);
-
-        // Find the print callback, since we mocked that out during this test.
-        Bundle printOption = null;
-        for (Parcelable parcelable : actions) {
-            Bundle bundle = (Bundle) parcelable;
-            if (TextUtils.equals(ContextUtils.getApplicationContext().getString(
-                                         R.string.print_share_activity_title),
-                        bundle.getString(KEY_CHOOSER_ACTION_NAME))) {
-                printOption = bundle;
-                break;
-            }
-        }
-
-        Assert.assertNotNull("Print option is null when the callback is provided.", printOption);
-
-        PendingIntent action = printOption.getParcelable(KEY_CHOOSER_ACTION_ACTION);
-        action.send();
-        ShadowLooper.idleMainLooper();
+        chooseCustomAction(intent, R.string.print_share_activity_title);
         Assert.assertEquals("Print callback is not called.", 1, mPrintCallback.getCallCount());
         Assert.assertEquals(
                 "TargetChosenCallback is not called.", 1, callbackHelper.getCallCount());
@@ -456,6 +433,35 @@
         assertCustomActions(chooserIntent, R.string.sharing_long_screenshot);
     }
 
+    @Test
+    @Config(shadows = {ShadowBuildCompatForU.class, ShadowChooserActionHelper.class,
+                    ShadowQrCodeDialog.class})
+    public void
+    chooseQRCodeAction() throws CanceledException {
+        Uri testImageUri = Uri.parse("content://test.image.uri");
+        ShareParams params = new ShareParams.Builder(mWindow, "", "")
+                                     .setFileContentType("image/png")
+                                     .setSingleImageUri(testImageUri)
+                                     .setBypassFixingDomDistillerUrl(true)
+                                     .build();
+        ChromeShareExtras chromeShareExtras =
+                new ChromeShareExtras.Builder()
+                        .setDetailedContentType(DetailedContentType.IMAGE)
+                        .setContentUrl(JUnitTestGURLs.getGURL(JUnitTestGURLs.GOOGLE_URL))
+                        .setImageSrcUrl(JUnitTestGURLs.getGURL(JUnitTestGURLs.GOOGLE_URL_DOGS))
+                        .build();
+
+        mController.showShareSheet(params, chromeShareExtras, 1L);
+
+        Intent intent = Shadows.shadowOf((Activity) mActivity).peekNextStartedActivity();
+        assertCustomActions(intent, R.string.sharing_long_screenshot,
+                R.string.send_tab_to_self_share_activity_title, R.string.qr_code_share_icon_label);
+        chooseCustomAction(intent, R.string.qr_code_share_icon_label);
+
+        Assert.assertEquals("Last URL does not match content being shared.",
+                JUnitTestGURLs.GOOGLE_URL_DOGS, ShadowQrCodeDialog.sLastUrl);
+    }
+
     private void setFaviconToFetchForTest(Bitmap favicon) {
         doAnswer(invocation -> {
             FaviconHelper.FaviconImageCallback callback = invocation.getArgument(4);
@@ -495,6 +501,31 @@
                 "Actions and/or the order does not match.", expectedString, actualString);
     }
 
+    private void chooseCustomAction(Intent chooserIntent, @StringRes int iconLabel)
+            throws CanceledException {
+        Parcelable[] actions =
+                chooserIntent.getParcelableArrayExtra(INTENT_EXTRA_CHOOSER_CUSTOM_ACTIONS);
+        Assert.assertTrue("More than one action is provided.", actions.length > 0);
+
+        // Find the print callback, since we mocked that out during this test.
+        Bundle expectAction = null;
+        for (Parcelable parcelable : actions) {
+            Bundle bundle = (Bundle) parcelable;
+            if (TextUtils.equals(
+                        ContextUtils.getApplicationContext().getResources().getString(iconLabel),
+                        bundle.getString(KEY_CHOOSER_ACTION_NAME))) {
+                expectAction = bundle;
+                break;
+            }
+        }
+
+        Assert.assertNotNull("Print option is null when the callback is provided.", expectAction);
+
+        PendingIntent action = expectAction.getParcelable(KEY_CHOOSER_ACTION_ACTION);
+        action.send();
+        ShadowLooper.idleMainLooper();
+    }
+
     /**
      * Test implementation to build a ChooserAction.
      */
@@ -563,4 +594,15 @@
             mRealObj.onSelectorReady(fail ? "" : SELECTOR_FOR_LINK_TO_TEXT);
         }
     }
+
+    @Implements(QrCodeDialog.class)
+    static class ShadowQrCodeDialog {
+        static @Nullable String sLastUrl;
+
+        @Implementation
+        protected static QrCodeDialog newInstance(String url, WindowAndroid windowAndroid) {
+            sLastUrl = url;
+            return Mockito.mock(QrCodeDialog.class);
+        }
+    }
 }
diff --git a/chrome/browser/supervised_user/chromeos/web_content_handler_impl.cc b/chrome/browser/supervised_user/chromeos/web_content_handler_impl.cc
index c7130cec..0ed4c33 100644
--- a/chrome/browser/supervised_user/chromeos/web_content_handler_impl.cc
+++ b/chrome/browser/supervised_user/chromeos/web_content_handler_impl.cc
@@ -4,13 +4,7 @@
 
 #include "chrome/browser/supervised_user/chromeos/web_content_handler_impl.h"
 
-#include "base/check.h"
 #include "base/functional/bind.h"
-#include "base/functional/callback.h"
-#include "base/logging.h"
-#include "base/notreached.h"
-#include "chrome/browser/ash/crosapi/crosapi_manager.h"
-#include "chrome/browser/ash/crosapi/parent_access_ash.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_key.h"
 #include "chrome/browser/supervised_user/chromeos/supervised_user_favicon_request_handler.h"
@@ -25,6 +19,12 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/gfx/image/image_skia.h"
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+#include "chrome/browser/ash/crosapi/crosapi_ash.h"
+#include "chrome/browser/ash/crosapi/crosapi_manager.h"
+#include "chrome/browser/ash/crosapi/parent_access_ash.h"
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
 namespace {
 
 supervised_user::WebContentHandler::LocalApprovalResult
@@ -92,6 +92,7 @@
     const GURL& url,
     const std::u16string& child_display_name,
     ApprovalRequestInitiatedCallback callback) {
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   CHECK(web_contents_);
   supervised_user::SupervisedUserSettingsService* settings_service =
       SupervisedUserSettingsServiceFactory::GetForKey(
@@ -100,16 +101,18 @@
 
   crosapi::mojom::ParentAccess* parent_access =
       crosapi::CrosapiManager::Get()->crosapi_ash()->parent_access_ash();
-  DCHECK(parent_access);
-
-  gfx::ImageSkia favicon = favicon_handler_->GetFaviconOrFallback();
+  CHECK(parent_access);
 
   parent_access->GetWebsiteParentApproval(
-      url.GetWithEmptyPath(), child_display_name, favicon,
+      url.GetWithEmptyPath(), child_display_name,
+      favicon_handler_->GetFaviconOrFallback(),
       base::BindOnce(&WebContentHandlerImpl::OnLocalApprovalRequestCompleted,
                      weak_ptr_factory_.GetWeakPtr(),
                      std::ref(*settings_service), url, base::TimeTicks::Now()));
   std::move(callback).Run(true);
+#else   // Local Web approvals not yet supported on Lacros.
+  NOTREACHED_NORETURN();
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
 void WebContentHandlerImpl::ShowFeedback(GURL url, std::u16string reason) {
diff --git a/chrome/browser/supervised_user/chromeos/web_content_handler_impl.h b/chrome/browser/supervised_user/chromeos/web_content_handler_impl.h
index 8995769..e1c8094c 100644
--- a/chrome/browser/supervised_user/chromeos/web_content_handler_impl.h
+++ b/chrome/browser/supervised_user/chromeos/web_content_handler_impl.h
@@ -9,8 +9,8 @@
 #include <string>
 
 #include "base/memory/weak_ptr.h"
-#include "chrome/browser/ash/crosapi/crosapi_ash.h"
 #include "chrome/browser/supervised_user/chrome_web_content_handler_base.h"
+#include "chromeos/crosapi/mojom/parent_access.mojom.h"
 #include "ui/gfx/image/image_skia.h"
 #include "url/gurl.h"
 
@@ -22,7 +22,7 @@
 
 class SupervisedUserFaviconRequestHandler;
 
-// Chrome Ash specific implementation of web content handler.
+// Chrome OS specific implementation of web content handler.
 class WebContentHandlerImpl : public ChromeWebContentHandlerBase {
  public:
   WebContentHandlerImpl(content::WebContents* web_contents,
diff --git a/chrome/browser/supervised_user/supervised_user_navigation_observer.cc b/chrome/browser/supervised_user/supervised_user_navigation_observer.cc
index b8c0385b..91cf3cac 100644
--- a/chrome/browser/supervised_user/supervised_user_navigation_observer.cc
+++ b/chrome/browser/supervised_user/supervised_user_navigation_observer.cc
@@ -41,7 +41,7 @@
 #include "chrome/browser/supervised_user/android/web_content_handler_impl.h"
 #endif
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_CHROMEOS)
 #include "chrome/browser/supervised_user/chromeos/web_content_handler_impl.h"
 #endif
 
@@ -52,7 +52,7 @@
     GURL url,
     Profile* profile,
     int frame_id) {
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_CHROMEOS)
   return std::make_unique<WebContentHandlerImpl>(
       web_contents, url,
       *LargeIconServiceFactory::GetForBrowserContext(profile), frame_id);
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeader.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeader.java
index 0522bb9b..0d97220 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeader.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeader.java
@@ -25,7 +25,6 @@
 import org.chromium.base.TraceEvent;
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.metrics.RecordHistogram;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.omnibox.geo.VisibleNetworks.VisibleCell;
 import org.chromium.chrome.browser.omnibox.geo.VisibleNetworks.VisibleWifi;
 import org.chromium.chrome.browser.profiles.Profile;
@@ -375,17 +374,6 @@
                 }
             }
 
-            // TODO(crbug.com/1330739): remove this.
-            if (!ChromeFeatureList.isEnabled(
-                        ChromeFeatureList.OPTIMIZE_GEOLOCATION_HEADER_GENERATION)) {
-                // These calls used to be necessary to record obsoleted
-                // histograms. We keep them here temporarily to measure the
-                // impact of removing them.
-                getLocationSource();
-                getGeolocationPermission(tab);
-                getDomainPermission(profile, url);
-            }
-
             // Proto encoding
             String locationProtoEncoding = encodeProtoLocation(locationToAttach);
             String visibleNetworksProtoEncoding =
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderUnitTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderUnitTest.java
index 98756af6c..e9fda239 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderUnitTest.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderUnitTest.java
@@ -30,14 +30,12 @@
 
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.JniMocker;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.omnibox.geo.VisibleNetworks.VisibleCell;
 import org.chromium.chrome.browser.omnibox.geo.VisibleNetworks.VisibleWifi;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.profiles.ProfileJni;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.test.util.browser.Features;
-import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
 import org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridge;
 import org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridgeJni;
 import org.chromium.components.content_settings.ContentSettingValues;
@@ -57,7 +55,6 @@
 @RunWith(BaseRobolectricTestRunner.class)
 @Config(manifest = Config.NONE)
 @LooperMode(LooperMode.Mode.LEGACY)
-@DisableFeatures({ChromeFeatureList.OPTIMIZE_GEOLOCATION_HEADER_GENERATION})
 public class GeolocationHeaderUnitTest {
     private static final String SEARCH_URL = "https://www.google.com/search?q=potatoes";
 
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc
index 1a9051f..1386d9fc 100644
--- a/chrome/browser/ui/browser_command_controller.cc
+++ b/chrome/browser/ui/browser_command_controller.cc
@@ -167,12 +167,6 @@
   return true;
 }
 
-bool IsPinnedHomeTab(Browser* browser) {
-  return web_app::AppBrowserController::IsWebApp(browser) &&
-         web_app::IsPinnedHomeTab(browser->tab_strip_model(),
-                                  browser->tab_strip_model()->active_index());
-}
-
 }  // namespace
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1408,9 +1402,11 @@
   bool is_isolated_app = current_web_contents->GetPrimaryMainFrame()
                              ->GetWebExposedIsolationLevel() >=
                          WebExposedIsolationLevel::kMaybeIsolatedApplication;
+  bool is_pinned_home_tab = web_app::IsPinnedHomeTab(
+      browser_->tab_strip_model(), browser_->tab_strip_model()->active_index());
   command_updater_.UpdateCommandEnabled(
       IDC_OPEN_IN_CHROME,
-      IsWebAppOrCustomTab() && !is_isolated_app && !IsPinnedHomeTab(browser_));
+      IsWebAppOrCustomTab() && !is_isolated_app && !is_pinned_home_tab);
 
   command_updater_.UpdateCommandEnabled(
       IDC_TOGGLE_REQUEST_TABLET_SITE,
@@ -1757,8 +1753,8 @@
 
 void BrowserCommandController::UpdateCommandsForTabStripStateChanged() {
   command_updater_.UpdateCommandEnabled(
-      IDC_CLOSE_TAB,
-      !IsPinnedHomeTab(browser_) || browser_->tab_strip_model()->count() == 1);
+      IDC_CLOSE_TAB, browser_->tab_strip_model()->IsTabClosable(
+                         browser_->tab_strip_model()->active_index()));
 }
 
 BrowserWindow* BrowserCommandController::window() {
diff --git a/chrome/browser/ui/performance_controls/performance_controls_metrics.cc b/chrome/browser/ui/performance_controls/performance_controls_metrics.cc
index d2b6e3f..da6b2bed 100644
--- a/chrome/browser/ui/performance_controls/performance_controls_metrics.cc
+++ b/chrome/browser/ui/performance_controls/performance_controls_metrics.cc
@@ -21,11 +21,6 @@
       "PerformanceControls.HighEfficiency.BubbleAction", type);
 }
 
-void RecordHighEfficiencyInfoIPHOpenSettings(bool success) {
-  base::UmaHistogramBoolean(
-      "PerformanceControls.HighEfficiency.InfoIPHOpenSettings", success);
-}
-
 void RecordHighEfficiencyIPHEnableMode(bool success) {
   base::UmaHistogramBoolean("PerformanceControls.HighEfficiency.IPHEnableMode",
                             success);
diff --git a/chrome/browser/ui/performance_controls/performance_controls_metrics.h b/chrome/browser/ui/performance_controls/performance_controls_metrics.h
index 2ae8f21..87f55ae 100644
--- a/chrome/browser/ui/performance_controls/performance_controls_metrics.h
+++ b/chrome/browser/ui/performance_controls/performance_controls_metrics.h
@@ -24,7 +24,6 @@
 void RecordBatterySaverBubbleAction(BatterySaverBubbleActionType type);
 void RecordBatterySaverIPHOpenSettings(bool success);
 void RecordHighEfficiencyBubbleAction(HighEfficiencyBubbleActionType type);
-void RecordHighEfficiencyInfoIPHOpenSettings(bool success);
 void RecordHighEfficiencyIPHEnableMode(bool success);
 
 #endif  // CHROME_BROWSER_UI_PERFORMANCE_CONTROLS_PERFORMANCE_CONTROLS_METRICS_H_
diff --git a/chrome/browser/ui/quick_answers/BUILD.gn b/chrome/browser/ui/quick_answers/BUILD.gn
index d9e6aca4..db7e7a5c 100644
--- a/chrome/browser/ui/quick_answers/BUILD.gn
+++ b/chrome/browser/ui/quick_answers/BUILD.gn
@@ -24,6 +24,8 @@
     "ui/rich_answers_pre_target_handler.h",
     "ui/rich_answers_translation_view.cc",
     "ui/rich_answers_translation_view.h",
+    "ui/rich_answers_unit_conversion_view.cc",
+    "ui/rich_answers_unit_conversion_view.h",
     "ui/rich_answers_view.cc",
     "ui/rich_answers_view.h",
     "ui/user_consent_view.cc",
diff --git a/chrome/browser/ui/quick_answers/ui/rich_answers_unit_conversion_view.cc b/chrome/browser/ui/quick_answers/ui/rich_answers_unit_conversion_view.cc
new file mode 100644
index 0000000..d54021c
--- /dev/null
+++ b/chrome/browser/ui/quick_answers/ui/rich_answers_unit_conversion_view.cc
@@ -0,0 +1,31 @@
+// 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/quick_answers/ui/rich_answers_unit_conversion_view.h"
+
+#include "base/functional/bind.h"
+#include "chrome/browser/ui/quick_answers/quick_answers_ui_controller.h"
+#include "chromeos/components/quick_answers/quick_answers_model.h"
+#include "ui/views/layout/fill_layout.h"
+
+// RichAnswersUnitConversionView
+// -----------------------------------------------------------
+
+RichAnswersUnitConversionView::RichAnswersUnitConversionView(
+    const quick_answers::QuickAnswer& result) {
+  InitLayout();
+
+  // TODO (b/274184290): Add custom focus behavior according to
+  // approved greenlines.
+}
+
+RichAnswersUnitConversionView::~RichAnswersUnitConversionView() = default;
+
+const char* RichAnswersUnitConversionView::GetClassName() const {
+  return "RichAnswersUnitConversionView";
+}
+
+void RichAnswersUnitConversionView::InitLayout() {
+  // TODO (b/265255270): Populate unit conversion view contents.
+}
diff --git a/chrome/browser/ui/quick_answers/ui/rich_answers_unit_conversion_view.h b/chrome/browser/ui/quick_answers/ui/rich_answers_unit_conversion_view.h
new file mode 100644
index 0000000..b296a40
--- /dev/null
+++ b/chrome/browser/ui/quick_answers/ui/rich_answers_unit_conversion_view.h
@@ -0,0 +1,34 @@
+// 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_QUICK_ANSWERS_UI_RICH_ANSWERS_UNIT_CONVERSION_VIEW_H_
+#define CHROME_BROWSER_UI_QUICK_ANSWERS_UI_RICH_ANSWERS_UNIT_CONVERSION_VIEW_H_
+
+#include "base/memory/raw_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/ui/quick_answers/ui/rich_answers_view.h"
+#include "ui/views/view.h"
+
+// A bubble style view to show QuickAnswer.
+class RichAnswersUnitConversionView : public views::View {
+ public:
+  explicit RichAnswersUnitConversionView(
+      const quick_answers::QuickAnswer& result);
+
+  RichAnswersUnitConversionView(const RichAnswersUnitConversionView&) = delete;
+  RichAnswersUnitConversionView& operator=(
+      const RichAnswersUnitConversionView&) = delete;
+
+  ~RichAnswersUnitConversionView() override;
+
+  // views::View:
+  const char* GetClassName() const override;
+
+ private:
+  void InitLayout();
+
+  base::WeakPtrFactory<RichAnswersUnitConversionView> weak_factory_{this};
+};
+
+#endif  // CHROME_BROWSER_UI_QUICK_ANSWERS_UI_RICH_ANSWERS_UNIT_CONVERSION_VIEW_H_
diff --git a/chrome/browser/ui/quick_answers/ui/rich_answers_view.cc b/chrome/browser/ui/quick_answers/ui/rich_answers_view.cc
index 400df35..63163e8 100644
--- a/chrome/browser/ui/quick_answers/ui/rich_answers_view.cc
+++ b/chrome/browser/ui/quick_answers/ui/rich_answers_view.cc
@@ -12,6 +12,7 @@
 #include "chrome/browser/ui/quick_answers/ui/rich_answers_definition_view.h"
 #include "chrome/browser/ui/quick_answers/ui/rich_answers_pre_target_handler.h"
 #include "chrome/browser/ui/quick_answers/ui/rich_answers_translation_view.h"
+#include "chrome/browser/ui/quick_answers/ui/rich_answers_unit_conversion_view.h"
 #include "chromeos/components/quick_answers/quick_answers_model.h"
 #include "chromeos/strings/grit/chromeos_strings.h"
 #include "components/vector_icons/vector_icons.h"
@@ -163,8 +164,10 @@
       return;
     }
     case quick_answers::ResultType::kUnitConversionResult:
+      content_view_ = base_view_->AddChildView(
+          std::make_unique<RichAnswersUnitConversionView>(result));
+      return;
     default: {
-      // TODO(b/259440976): Add child views for each result type.
       return;
     }
   }
diff --git a/chrome/browser/ui/tabs/tab_strip_model.cc b/chrome/browser/ui/tabs/tab_strip_model.cc
index a3b13fb..800732d7 100644
--- a/chrome/browser/ui/tabs/tab_strip_model.cc
+++ b/chrome/browser/ui/tabs/tab_strip_model.cc
@@ -50,6 +50,7 @@
 #include "chrome/browser/ui/user_notes/user_notes_controller.h"
 #include "chrome/browser/ui/web_applications/web_app_dialog_utils.h"
 #include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
+#include "chrome/browser/ui/web_applications/web_app_tabbed_utils.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
@@ -808,6 +809,10 @@
   return contents_data_[index]->blocked();
 }
 
+bool TabStripModel::IsTabClosable(int index) const {
+  return !web_app::IsPinnedHomeTab(this, index) || count() == 1;
+}
+
 absl::optional<tab_groups::TabGroupId> TabStripModel::GetTabGroupForTab(
     int index) const {
   return ContainsIndex(index) ? contents_data_[index]->group() : absl::nullopt;
diff --git a/chrome/browser/ui/tabs/tab_strip_model.h b/chrome/browser/ui/tabs/tab_strip_model.h
index 6f68f06..c1e901c 100644
--- a/chrome/browser/ui/tabs/tab_strip_model.h
+++ b/chrome/browser/ui/tabs/tab_strip_model.h
@@ -347,6 +347,9 @@
   // Returns true if the tab at |index| is blocked by a tab modal dialog.
   bool IsTabBlocked(int index) const;
 
+  // Returns true if the tab at |index| is allowed to be closed.
+  bool IsTabClosable(int index) const;
+
   // Returns the group that contains the tab at |index|, or nullopt if the tab
   // index is invalid or not grouped.
   absl::optional<tab_groups::TabGroupId> GetTabGroupForTab(
diff --git a/chrome/browser/ui/tabs/tab_style.cc b/chrome/browser/ui/tabs/tab_style.cc
index cb37a0e..ec1c357c 100644
--- a/chrome/browser/ui/tabs/tab_style.cc
+++ b/chrome/browser/ui/tabs/tab_style.cc
@@ -19,64 +19,68 @@
   return ui::TouchUiController::Get()->touch_ui() ? 24 : 20;
 }
 
-class GM2TabStyle : public TabStyle {};
-class ChromeRefresh2023TabStyle : public GM2TabStyle {};
+class GM2TabStyle : public TabStyle {
+ public:
+  ~GM2TabStyle() override = default;
+};
+class ChromeRefresh2023TabStyle : public GM2TabStyle {
+ public:
+  ~ChromeRefresh2023TabStyle() override = default;
+};
 
 }  // namespace
 
 TabStyle::~TabStyle() = default;
 
-// static
-int TabStyle::GetStandardWidth() {
+int TabStyle::GetStandardWidth() const {
   // The standard tab width is 240 DIP including both separators.
   constexpr int kTabWidth = 240;
   // The overlap includes one separator, so subtract it here.
   return kTabWidth + GetTabOverlap() - kSeparatorThickness;
 }
 
-// static
-int TabStyle::GetPinnedWidth() {
+int TabStyle::GetPinnedWidth() const {
   constexpr int kTabPinnedContentWidth = 24;
   return kTabPinnedContentWidth + GetContentsHorizontalInsetSize() * 2;
 }
 
-// static
-int TabStyle::GetTabOverlap() {
+int TabStyle::GetTabOverlap() const {
   return GetCornerRadius() * 2 + kSeparatorThickness;
 }
 
-// static
-int TabStyle::GetDragHandleExtension(int height) {
+int TabStyle::GetDragHandleExtension(int height) const {
   return (height - GetSeparatorHeight()) / 2 - 1;
 }
 
-// static
-gfx::Size TabStyle::GetSeparatorSize() {
+gfx::Size TabStyle::GetSeparatorSize() const {
   return gfx::Size(kSeparatorThickness, GetSeparatorHeight());
 }
 
-// static
-gfx::Size TabStyle::GetPreviewImageSize() {
+gfx::Size TabStyle::GetPreviewImageSize() const {
   constexpr float kTabHoverCardPreviewImageAspectRatio = 16.0f / 9.0f;
   const int width = GetStandardWidth();
   return gfx::Size(width, width / kTabHoverCardPreviewImageAspectRatio);
 }
 
-// static
-int TabStyle::GetCornerRadius() {
+int TabStyle::GetCornerRadius() const {
   return views::LayoutProvider::Get()->GetCornerRadiusMetric(
       views::Emphasis::kHigh);
 }
 
-// static
-int TabStyle::GetContentsHorizontalInsetSize() {
+int TabStyle::GetContentsHorizontalInsetSize() const {
   return GetCornerRadius() * 2;
 }
 
-std::unique_ptr<const TabStyle> TabStyle::Create() {
-  // If refresh is turned on use ChromeRefresh23 styling.
-  if (features::IsChromeRefresh2023()) {
-    return std::make_unique<ChromeRefresh2023TabStyle>();
-  }
-  return std::make_unique<GM2TabStyle>();
+float TabStyle::GetSelectedTabOpacity() const {
+  return kDefaultSelectedTabOpacity;
+}
+
+// static
+const TabStyle* TabStyle::Get() {
+  static TabStyle* const tab_style =
+      features::IsChromeRefresh2023()
+          ? static_cast<TabStyle*>(new ChromeRefresh2023TabStyle())
+          : static_cast<TabStyle*>(new GM2TabStyle());
+
+  return tab_style;
 }
diff --git a/chrome/browser/ui/tabs/tab_style.h b/chrome/browser/ui/tabs/tab_style.h
index 9d835227..104f21f 100644
--- a/chrome/browser/ui/tabs/tab_style.h
+++ b/chrome/browser/ui/tabs/tab_style.h
@@ -104,28 +104,31 @@
 
   // Returns the preferred width of a single Tab, assuming space is
   // available.
-  static int GetStandardWidth();
+  virtual int GetStandardWidth() const;
 
   // Returns the width for pinned tabs. Pinned tabs always have this width.
-  static int GetPinnedWidth();
+  virtual int GetPinnedWidth() const;
 
   // Returns the overlap between adjacent tabs.
-  static int GetTabOverlap();
+  virtual int GetTabOverlap() const;
 
   // Gets the size of the separator drawn between tabs, if any.
-  static gfx::Size GetSeparatorSize();
+  virtual gfx::Size GetSeparatorSize() const;
 
   // Returns, for a tab of height |height|, how far the window top drag handle
   // can extend down into inactive tabs or the new tab button. This behavior
   // is not used in all cases.
-  static int GetDragHandleExtension(int height);
+  virtual int GetDragHandleExtension(int height) const;
 
   // Gets the preferred size for tab previews, which could be screencaps, hero
   // or og:image images, etc.
-  static gfx::Size GetPreviewImageSize();
+  virtual gfx::Size GetPreviewImageSize() const;
 
   // Returns the radius of the outer corners of the tab shape.
-  static int GetCornerRadius();
+  virtual int GetCornerRadius() const;
+
+  // Opacity of the active tab background painted over inactive selected tabs.
+  virtual float GetSelectedTabOpacity() const;
 
   // The largest valid value of TabStyle::GetZValue(). Currently,
   // GM2TabStyle::GetZValue is the only implementation, and it can't return
@@ -134,7 +137,7 @@
 
   static constexpr float kDefaultSelectedTabOpacity = 0.75f;
 
-  static std::unique_ptr<const TabStyle> Create();
+  static const TabStyle* Get();
 
  protected:
   // Avoid implicitly-deleted constructor.
@@ -142,7 +145,7 @@
 
   // Returns how far from the leading and trailing edges of a tab the contents
   // should actually be laid out.
-  static int GetContentsHorizontalInsetSize();
+  int GetContentsHorizontalInsetSize() const;
 };
 
 #endif  // CHROME_BROWSER_UI_TABS_TAB_STYLE_H_
diff --git a/chrome/browser/ui/thumbnails/thumbnail_tab_helper.cc b/chrome/browser/ui/thumbnails/thumbnail_tab_helper.cc
index 4e722c20..ab1473d 100644
--- a/chrome/browser/ui/thumbnails/thumbnail_tab_helper.cc
+++ b/chrome/browser/ui/thumbnails/thumbnail_tab_helper.cc
@@ -49,7 +49,7 @@
 
   // Compute minimum sizes for multiple uses of the thumbnail - currently,
   // tablet tabstrip previews and tab hover card preview images.
-  gfx::Size min_target_size = TabStyle::GetPreviewImageSize();
+  gfx::Size min_target_size = TabStyle::Get()->GetPreviewImageSize();
   min_target_size.SetToMax(
       {kMinThumbnailDimensionForTablet, kMinThumbnailDimensionForTablet});
 
diff --git a/chrome/browser/ui/toolbar/app_menu_model.cc b/chrome/browser/ui/toolbar/app_menu_model.cc
index dd780fd..e3cdbdc 100644
--- a/chrome/browser/ui/toolbar/app_menu_model.cc
+++ b/chrome/browser/ui/toolbar/app_menu_model.cc
@@ -134,7 +134,15 @@
       UpgradeDetector::GetInstance()->is_outdated_install_no_au()) {
     return l10n_util::GetStringUTF16(IDS_UPGRADE_BUBBLE_MENU_ITEM);
   } else {
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING) && \
+    (BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX))
+    return l10n_util::GetStringUTF16(
+        base::FeatureList::IsEnabled(features::kUpdateTextOptions)
+            ? IDS_RELAUNCH_TO_UPDATE_ALT
+            : IDS_RELAUNCH_TO_UPDATE);
+#else
     return l10n_util::GetStringUTF16(IDS_RELAUNCH_TO_UPDATE);
+#endif
   }
 }
 
diff --git a/chrome/browser/ui/ui_features.cc b/chrome/browser/ui/ui_features.cc
index 8b53c74..2cc87e8 100644
--- a/chrome/browser/ui/ui_features.cc
+++ b/chrome/browser/ui/ui_features.cc
@@ -273,6 +273,18 @@
              "TopChromeWebUIUsesSpareRenderer",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
+// Enables alternate update-related text to be displayed in browser app menu
+// button, menu item and confirmation dialog.
+BASE_FEATURE(kUpdateTextOptions,
+             "UpdateTextOptions",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+// Used to present different flavors of update strings in browser app menu
+// button.
+const base::FeatureParam<int> kUpdateTextOptionNumber{
+    &kUpdateTextOptions, "UpdateTextOptionNumber", 1};
+#endif
+
 // This enables enables persistence of a WebContents in a 1-to-1 association
 // with the current Profile for WebUI bubbles. See https://crbug.com/1177048.
 BASE_FEATURE(kWebUIBubblePerProfilePersistence,
diff --git a/chrome/browser/ui/ui_features.h b/chrome/browser/ui/ui_features.h
index 96d57a48..fbc1030 100644
--- a/chrome/browser/ui/ui_features.h
+++ b/chrome/browser/ui/ui_features.h
@@ -185,6 +185,11 @@
 
 BASE_DECLARE_FEATURE(kTopChromeWebUIUsesSpareRenderer);
 
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
+BASE_DECLARE_FEATURE(kUpdateTextOptions);
+extern const base::FeatureParam<int> kUpdateTextOptionNumber;
+#endif
+
 BASE_DECLARE_FEATURE(kWebUIBubblePerProfilePersistence);
 
 BASE_DECLARE_FEATURE(kWebUITabStrip);
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
index 5b51144..60ccdbf 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
@@ -198,6 +198,7 @@
     views::InstallPillHighlightPathGenerator(this);
 
     SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);
+    views::FocusRing::Get(this)->SetOutsetFocusRingDisabled(true);
     SetHideInkDropWhenShowingContextMenu(false);
 
     show_animation_ = std::make_unique<gfx::SlideAnimation>(this);
diff --git a/chrome/browser/ui/views/frame/tab_strip_region_view_unittest.cc b/chrome/browser/ui/views/frame/tab_strip_region_view_unittest.cc
index 062793c..ad6613f 100644
--- a/chrome/browser/ui/views/frame/tab_strip_region_view_unittest.cc
+++ b/chrome/browser/ui/views/frame/tab_strip_region_view_unittest.cc
@@ -209,7 +209,8 @@
 // TabStripRegionViewTestWithScrollingEnabled.TabStripCanBeLargerThanContainer.
 TEST_F(TabStripRegionViewTestWithScrollingDisabled,
        TabStripCannotBeLargerThanContainer) {
-  const int minimum_active_width = TabStyleViews::GetMinimumInactiveWidth();
+  const int minimum_active_width =
+      TabStyleViews::Create()->GetMinimumInactiveWidth();
   controller_->AddTab(0, TabActive::kActive);
   CompleteAnimationAndLayout();
 
@@ -249,7 +250,8 @@
 // TabStripCannotBeLargerThanContainer.
 TEST_F(TabStripRegionViewTestWithScrollingEnabled,
        TabStripCanBeLargerThanContainer) {
-  const int minimum_active_width = TabStyleViews::GetMinimumInactiveWidth();
+  const int minimum_active_width =
+      TabStyleViews::Create()->GetMinimumInactiveWidth();
   controller_->AddTab(0, TabActive::kActive);
   CompleteAnimationAndLayout();
 
@@ -276,7 +278,8 @@
 
 TEST_F(TabStripRegionViewTestWithScrollingEnabled,
        TabStripScrollButtonsNotInWindowCaption) {
-  const int minimum_active_width = TabStyleViews::GetMinimumInactiveWidth();
+  const int minimum_active_width =
+      TabStyleViews::Create()->GetMinimumInactiveWidth();
   controller_->AddTab(0, TabActive::kActive);
   CompleteAnimationAndLayout();
 
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls_icon_view.cc b/chrome/browser/ui/views/location_bar/cookie_controls_icon_view.cc
index d53343e8..a7b8f49 100644
--- a/chrome/browser/ui/views/location_bar/cookie_controls_icon_view.cc
+++ b/chrome/browser/ui/views/location_bar/cookie_controls_icon_view.cc
@@ -13,6 +13,8 @@
 #include "chrome/browser/ui/views/location_bar/cookie_controls_bubble_view.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/content_settings/browser/ui/cookie_controls_controller.h"
+#include "components/omnibox/browser/omnibox_field_trial.h"
+#include "components/omnibox/browser/vector_icons.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -119,6 +121,12 @@
 }
 
 const gfx::VectorIcon& CookieControlsIconView::GetVectorIcon() const {
+  if (OmniboxFieldTrial::IsChromeRefreshIconsEnabled()) {
+    return status_ == CookieControlsStatus::kDisabledForSite
+               ? omnibox::kCookieChromeRefreshIcon
+               : omnibox::kCookieCrossedChromeRefreshIcon;
+  }
+
   return status_ == CookieControlsStatus::kDisabledForSite
              ? views::kEyeIcon
              : views::kEyeCrossedIcon;
diff --git a/chrome/browser/ui/views/location_bar/find_bar_icon.cc b/chrome/browser/ui/views/location_bar/find_bar_icon.cc
index 57fa941..a8f903d 100644
--- a/chrome/browser/ui/views/location_bar/find_bar_icon.cc
+++ b/chrome/browser/ui/views/location_bar/find_bar_icon.cc
@@ -8,6 +8,7 @@
 #include "chrome/browser/ui/find_bar/find_bar.h"
 #include "chrome/browser/ui/find_bar/find_bar_controller.h"
 #include "chrome/grit/generated_resources.h"
+#include "components/omnibox/browser/omnibox_field_trial.h"
 #include "components/omnibox/browser/vector_icons.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
@@ -55,7 +56,9 @@
 }
 
 const gfx::VectorIcon& FindBarIcon::GetVectorIcon() const {
-  return omnibox::kFindInPageIcon;
+  return OmniboxFieldTrial::IsChromeRefreshIconsEnabled()
+             ? omnibox::kFindInPageChromeRefreshIcon
+             : omnibox::kFindInPageIcon;
 }
 
 void FindBarIcon::UpdateImpl() {
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc
index 09b222c..995186c 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -187,7 +187,7 @@
              !v->GetOmniboxPopupView()->IsOpen();
     });
     if (features::IsChromeRefresh2023()) {
-      views::FocusRing::Get(this)->SetOutsetFocusRingDisabled();
+      views::FocusRing::Get(this)->SetOutsetFocusRingDisabled(true);
     }
     views::InstallPillHighlightPathGenerator(this);
 
diff --git a/chrome/browser/ui/views/page_action/page_action_icon_view.cc b/chrome/browser/ui/views/page_action/page_action_icon_view.cc
index 430c850..30b4d41 100644
--- a/chrome/browser/ui/views/page_action/page_action_icon_view.cc
+++ b/chrome/browser/ui/views/page_action/page_action_icon_view.cc
@@ -113,7 +113,7 @@
         },
         this));
     if (auto* focus_ring = views::FocusRing::Get(this); focus_ring) {
-      focus_ring->SetOutsetFocusRingDisabled();
+      focus_ring->SetOutsetFocusRingDisabled(true);
     }
   }
   // Only shows bubble after mouse is released.
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc b/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc
index 639480b..7e54608 100644
--- a/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc
+++ b/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc
@@ -10,6 +10,7 @@
 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
 #include "chrome/browser/ui/views/passwords/password_bubble_view_base.h"
 #include "chrome/grit/generated_resources.h"
+#include "components/omnibox/browser/omnibox_field_trial.h"
 #include "components/password_manager/core/common/password_manager_ui.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -81,7 +82,9 @@
 }
 
 const gfx::VectorIcon& ManagePasswordsIconViews::GetVectorIcon() const {
-  return kKeyIcon;
+  return OmniboxFieldTrial::IsChromeRefreshIconsEnabled()
+             ? kKeyChromeRefreshIcon
+             : kKeyIcon;
 }
 
 std::u16string ManagePasswordsIconViews::GetTextForTooltipAndAccessibleName()
diff --git a/chrome/browser/ui/views/performance_controls/high_efficiency_chip_view.cc b/chrome/browser/ui/views/performance_controls/high_efficiency_chip_view.cc
index b2b3041..ca54137 100644
--- a/chrome/browser/ui/views/performance_controls/high_efficiency_chip_view.cc
+++ b/chrome/browser/ui/views/performance_controls/high_efficiency_chip_view.cc
@@ -35,12 +35,6 @@
 
 // The duration that the chip should be expanded for.
 constexpr base::TimeDelta kChipAnimationDuration = base::Seconds(12);
-// The delay before the IPH should be potentially shown. This should be less
-// than kChipAnimationDuration but longer than kIconLabelAnimationDurationMs.
-constexpr base::TimeDelta kIPHDelayDuration = base::Seconds(1);
-
-// We want this to show up before the chip finishes animating.
-static_assert(kIPHDelayDuration < kChipAnimationDuration);
 
 }  // namespace
 
@@ -126,14 +120,6 @@
       AnimateOut();
       ResetSlideAnimation(false);
     }
-
-    if (base::FeatureList::IsEnabled(
-            feature_engagement::kIPHHighEfficiencyInfoModeFeature)) {
-      // Delay the IPH to ensure the chip is not animating when it appears.
-      timer_.Start(FROM_HERE, kIPHDelayDuration,
-                   base::BindOnce(&HighEfficiencyChipView::MaybeShowIPH,
-                                  weak_ptr_factory_.GetWeakPtr()));
-    }
   } else {
     AnimateOut();
     ResetSlideAnimation(false);
@@ -151,10 +137,6 @@
 
   BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser_);
 
-  // If the IPH is currently open, close it before opening the dialog.
-  browser_view->CloseFeaturePromo(
-      feature_engagement::kIPHHighEfficiencyInfoModeFeature);
-
   // Open the dialog bubble.
   View* anchor_view = browser_view->toolbar_button_provider()->GetAnchorView(
       PageActionIconType::kHighEfficiency);
@@ -175,26 +157,6 @@
   return bubble_;
 }
 
-void HighEfficiencyChipView::MaybeShowIPH() {
-  if (browser_->window() != nullptr) {
-    bool const promo_shown = browser_->window()->MaybeShowFeaturePromo(
-        feature_engagement::kIPHHighEfficiencyInfoModeFeature, {},
-        base::BindOnce(&HighEfficiencyChipView::OnIPHClosed,
-                       weak_ptr_factory_.GetWeakPtr()));
-    // While the IPH is showing, pause the animation of the chip so it doesn't
-    // animate closed.
-    if (promo_shown) {
-      PauseAnimation();
-      SetHighlighted(true);
-    }
-  }
-}
-
-void HighEfficiencyChipView::OnIPHClosed() {
-  SetHighlighted(false);
-  UnpauseAnimation();
-}
-
 void HighEfficiencyChipView::OnHighEfficiencyModeChanged() {
   auto* manager = performance_manager::user_tuning::
       UserPerformanceTuningManager::GetInstance();
diff --git a/chrome/browser/ui/views/performance_controls/high_efficiency_chip_view.h b/chrome/browser/ui/views/performance_controls/high_efficiency_chip_view.h
index d849d92c..0b805f34 100644
--- a/chrome/browser/ui/views/performance_controls/high_efficiency_chip_view.h
+++ b/chrome/browser/ui/views/performance_controls/high_efficiency_chip_view.h
@@ -54,9 +54,6 @@
   const gfx::VectorIcon& GetVectorIcon() const override;
 
  private:
-  void MaybeShowIPH();
-  void OnIPHClosed();
-
   // performance_manager::user_tuning::UserPerformanceTuningManager::Observer:
   // Checks whether high efficiency mode is currently enabled.
   void OnHighEfficiencyModeChanged() override;
diff --git a/chrome/browser/ui/views/performance_controls/high_efficiency_chip_view_browsertest.cc b/chrome/browser/ui/views/performance_controls/high_efficiency_chip_view_browsertest.cc
index aed3dbb..16014fbb 100644
--- a/chrome/browser/ui/views/performance_controls/high_efficiency_chip_view_browsertest.cc
+++ b/chrome/browser/ui/views/performance_controls/high_efficiency_chip_view_browsertest.cc
@@ -61,10 +61,10 @@
   ~HighEfficiencyChipViewBrowserTest() override = default;
 
   void SetUp() override {
-    iph_features_.InitForDemo(
-        feature_engagement::kIPHHighEfficiencyInfoModeFeature,
+    scoped_feature_list_.InitWithFeaturesAndParameters(
         {{performance_manager::features::kHighEfficiencyModeAvailable,
-          {{"default_state", "true"}, {"time_before_discard", "1h"}}}});
+          {{"default_state", "true"}, {"time_before_discard", "1h"}}}},
+        {});
 
     InProcessBrowserTest::SetUp();
   }
@@ -130,36 +130,6 @@
     manager->DiscardPageForTesting(contents);
   }
 
-  void WaitForIPHToShow() {
-    views::NamedWidgetShownWaiter waiter(
-        views::test::AnyWidgetTestPasskey{},
-        user_education::HelpBubbleView::kViewClassName);
-    waiter.WaitIfNeededAndGet();
-  }
-
-  user_education::HelpBubbleView* GetHelpBubbleView() {
-    return GetFeaturePromoController()
-        ->promo_bubble_for_testing()
-        ->AsA<user_education::HelpBubbleViews>()
-        ->bubble_view();
-  }
-
-  void ClickIPHCancelButton() {
-    views::test::WidgetDestroyedWaiter waiter(GetHelpBubbleView()->GetWidget());
-    views::test::InteractionTestUtilSimulatorViews::PressButton(
-        GetHelpBubbleView()->GetDefaultButtonForTesting(),
-        ui::test::InteractionTestUtil::InputType::kMouse);
-    waiter.Wait();
-  }
-
-  void ClickIPHSettingsButton() {
-    views::test::WidgetDestroyedWaiter waiter(GetHelpBubbleView()->GetWidget());
-    views::test::InteractionTestUtilSimulatorViews::PressButton(
-        GetHelpBubbleView()->GetNonDefaultButtonForTesting(0),
-        ui::test::InteractionTestUtil::InputType::kMouse);
-    waiter.Wait();
-  }
-
   views::InkDropState GetInkDropState() {
     return views::InkDrop::Get(GetHighEfficiencyChipView())
         ->GetInkDrop()
@@ -167,7 +137,7 @@
   }
 
  private:
-  feature_engagement::test::ScopedIphFeatureList iph_features_;
+  base::test::ScopedFeatureList scoped_feature_list_;
   base::SimpleTestTickClock test_clock_;
   resource_coordinator::ScopedSetTickClockForTesting
       scoped_set_tick_clock_for_testing_;
diff --git a/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view.cc b/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view.cc
index 8f7ffce..d2f8872 100644
--- a/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view.cc
+++ b/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view.cc
@@ -47,8 +47,10 @@
       return base_url.Resolve(chrome::kChromeUIPrivacySandboxDialogNoticePath);
     case PrivacySandboxService::PromptType::kM1NoticeEEA:
       return net::AppendQueryParameter(combined_dialog_url, "step", "notice");
-    case PrivacySandboxService::PromptType::kNone:
     case PrivacySandboxService::PromptType::kM1NoticeRestricted:
+      return base_url.Resolve(
+          chrome::kChromeUIPrivacySandboxDialogNoticeRestrictedPath);
+    case PrivacySandboxService::PromptType::kNone:
       NOTREACHED_NORETURN();
   }
 }
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_button.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_button.cc
index 49e613b0..8eccf03 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_button.cc
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_button.cc
@@ -67,7 +67,8 @@
                                      ui::ColorId icon_color) {
   SetImageModel(views::Button::STATE_NORMAL,
                 ui::ImageModel::FromVectorIcon(icon, icon_color, icon_size));
-  views::InkDrop::Get(this)->SetBaseColor(icon_color);
+  DCHECK(views::InkDrop::Get(this));
+  views::InkDrop::Get(this)->SetBaseColorId(icon_color);
 }
 
 void ReadAnythingMenuButton::SetDropdownColorIds(ui::ColorId background_color,
diff --git a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
index f4a5c3a..73eff72 100644
--- a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
+++ b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
@@ -318,6 +318,10 @@
 
 bool BrowserTabStripController::BeforeCloseTab(int model_index,
                                                CloseTabSource source) {
+  if (!model_->IsTabClosable(model_index)) {
+    return false;
+  }
+
   // Only consider pausing the close operation if this is the last remaining
   // tab (since otherwise closing it won't close the browser window).
   if (GetCount() > 1)
diff --git a/chrome/browser/ui/views/tabs/compound_tab_container.cc b/chrome/browser/ui/views/tabs/compound_tab_container.cc
index 7bbd24e..143f29f 100644
--- a/chrome/browser/ui/views/tabs/compound_tab_container.cc
+++ b/chrome/browser/ui/views/tabs/compound_tab_container.cc
@@ -692,8 +692,8 @@
       gfx::Rect(pinned_tab_container_->GetPreferredSize()));
 
   // Unpinned container can have whatever is left over.
-  const int unpinned_container_leading_x =
-      std::max(0, pinned_tab_container_->width() - TabStyle::GetTabOverlap());
+  const int unpinned_container_leading_x = std::max(
+      0, pinned_tab_container_->width() - TabStyle::Get()->GetTabOverlap());
   const int available_width = width() - unpinned_container_leading_x;
 
   const gfx::Size pref_size = unpinned_tab_container_->GetPreferredSize();
@@ -1006,7 +1006,7 @@
   return NumPinnedTabs() > 0
              ? pinned_tab_container_->GetIdealBounds(NumPinnedTabs() - 1)
                        .right() -
-                   TabStyle::GetTabOverlap()
+                   TabStyle::Get()->GetTabOverlap()
              : 0;
 }
 
@@ -1022,8 +1022,8 @@
   gfx::Size largest_container = pinned_size;
   largest_container.SetToMax(unpinned_size);
 
-  const int width_with_overlap =
-      pinned_size.width() + unpinned_size.width() - TabStyle::GetTabOverlap();
+  const int width_with_overlap = pinned_size.width() + unpinned_size.width() -
+                                 TabStyle::Get()->GetTabOverlap();
   return gfx::Size(std::max(width_with_overlap, largest_container.width()),
                    largest_container.height());
 }
diff --git a/chrome/browser/ui/views/tabs/compound_tab_container_unittest.cc b/chrome/browser/ui/views/tabs/compound_tab_container_unittest.cc
index d30fdb77..c63bede 100644
--- a/chrome/browser/ui/views/tabs/compound_tab_container_unittest.cc
+++ b/chrome/browser/ui/views/tabs/compound_tab_container_unittest.cc
@@ -389,7 +389,7 @@
   AddTab(0, TabPinned::kUnpinned, absl::nullopt, TabActive::kActive);
 
   // Create just enough tabs so tabs are not full size.
-  const int standard_width = TabStyleViews::GetStandardWidth();
+  const int standard_width = TabStyleViews::Create()->GetStandardWidth();
   while (tab_container_->GetActiveTabWidth() == standard_width) {
     AddTab(0, TabPinned::kUnpinned);
     tab_container_->CompleteAnimationAndLayout();
@@ -425,7 +425,7 @@
   AddTab(1, TabPinned::kUnpinned, absl::nullopt, TabActive::kInactive);
 
   // Create just enough (pinned) tabs so the active tab is not full size.
-  const int standard_width = TabStyleViews::GetStandardWidth();
+  const int standard_width = TabStyleViews::Create()->GetStandardWidth();
   while (tab_container_->GetActiveTabWidth() == standard_width) {
     AddTab(0, TabPinned::kPinned, absl::nullopt, TabActive::kInactive);
     tab_container_->CompleteAnimationAndLayout();
@@ -458,7 +458,7 @@
   AddTab(1, TabPinned::kUnpinned, absl::nullopt, TabActive::kActive);
 
   // Create just enough (pinned) tabs so the active tab is not full size.
-  const int standard_width = TabStyleViews::GetStandardWidth();
+  const int standard_width = TabStyleViews::Create()->GetStandardWidth();
   while (tab_container_->GetActiveTabWidth() == standard_width) {
     AddTab(0, TabPinned::kPinned);
     tab_container_->CompleteAnimationAndLayout();
diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc
index 56a48b7..8972016a 100644
--- a/chrome/browser/ui/views/tabs/tab.cc
+++ b/chrome/browser/ui/views/tabs/tab.cc
@@ -661,7 +661,8 @@
 }
 
 gfx::Size Tab::CalculatePreferredSize() const {
-  return gfx::Size(TabStyle::GetStandardWidth(), GetLayoutConstant(TAB_HEIGHT));
+  return gfx::Size(tab_style()->GetStandardWidth(),
+                   GetLayoutConstant(TAB_HEIGHT));
 }
 
 void Tab::PaintChildren(const views::PaintInfo& info) {
@@ -717,9 +718,9 @@
 }
 
 TabSizeInfo Tab::GetTabSizeInfo() const {
-  return {TabStyle::GetPinnedWidth(), TabStyleViews::GetMinimumActiveWidth(),
-          TabStyleViews::GetMinimumInactiveWidth(),
-          TabStyle::GetStandardWidth()};
+  return {tab_style()->GetPinnedWidth(), tab_style()->GetMinimumActiveWidth(),
+          tab_style()->GetMinimumInactiveWidth(),
+          tab_style()->GetStandardWidth()};
 }
 
 void Tab::SetClosing(bool closing) {
@@ -913,7 +914,7 @@
                                       int visual_width) const {
   if (ShouldRenderAsNormalTab())
     return;
-  const int pinned_width = TabStyle::GetPinnedWidth();
+  const int pinned_width = tab_style()->GetPinnedWidth();
   const int ideal_delta = width() - pinned_width;
   const int ideal_x = (pinned_width - visual_width) / 2;
   // TODO(crbug.com/533570): This code is broken when the current width is less
@@ -1040,7 +1041,7 @@
 }
 
 bool Tab::ShouldRenderAsNormalTab() const {
-  return !data().pinned || (width() >= (TabStyle::GetPinnedWidth() +
+  return !data().pinned || (width() >= (tab_style()->GetPinnedWidth() +
                                         kPinnedTabExtraWidthToRenderAsNormal));
 }
 
@@ -1076,7 +1077,7 @@
   // There may be no focus ring when the tab is closing.
   if (auto* focus_ring = views::FocusRing::Get(this); focus_ring) {
     focus_ring->SetColorId(colors.focus_ring_color);
-    focus_ring->SetOutsetFocusRingDisabled();
+    focus_ring->SetOutsetFocusRingDisabled(true);
   }
   SchedulePaint();
 }
diff --git a/chrome/browser/ui/views/tabs/tab_container_impl.cc b/chrome/browser/ui/views/tabs/tab_container_impl.cc
index a42203c..5089bc1 100644
--- a/chrome/browser/ui/views/tabs/tab_container_impl.cc
+++ b/chrome/browser/ui/views/tabs/tab_container_impl.cc
@@ -528,7 +528,7 @@
     // drag handle, to increase draggability.  This region starts 1 DIP above
     // the top of the separator.
     const int drag_handle_extension =
-        TabStyle::GetDragHandleExtension(height());
+        TabStyle::Get()->GetDragHandleExtension(height());
 
     // A hit on an inactive tab is in the content area unless it is in the thin
     // strip mentioned above.
@@ -705,7 +705,7 @@
     const bool is_collapsed =
         (current_group.has_value() &&
          controller_->IsGroupCollapsed(current_group.value()) &&
-         tab->bounds().width() <= TabStyle::GetTabOverlap());
+         tab->bounds().width() <= tab->tab_style()->GetTabOverlap());
     const bool should_be_visible = is_collapsed ? false : last_tab_visible;
 
     // If we change the visibility of a tab in a group, we must recalculate that
@@ -1118,7 +1118,7 @@
   bounds.set_height(GetLayoutConstant(TAB_HEIGHT));
 
   // Adjust the starting bounds of the new tab.
-  const int tab_overlap = TabStyle::GetTabOverlap();
+  const int tab_overlap = TabStyle::Get()->GetTabOverlap();
   if (model_index > 0) {
     // If we have a tab to our left, start at its right edge.
     bounds.set_x(GetTabAtModelIndex(model_index - 1)->bounds().right() -
@@ -1190,7 +1190,7 @@
 gfx::Rect TabContainerImpl::GetTargetBoundsForClosingTab(
     Tab* tab,
     int former_model_index) const {
-  const int tab_overlap = TabStyle::GetTabOverlap();
+  const int tab_overlap = TabStyle::Get()->GetTabOverlap();
 
   // Compute the target bounds for animating this tab closed.  The tab's left
   // edge should stay joined to the right edge of the previous tab, if any.
@@ -1309,7 +1309,7 @@
 
   override_available_width_for_tabs_ =
       tabs_view_model_.ideal_bounds(model_count).right() - size_delta +
-      TabStyle::GetTabOverlap();
+      TabStyle::Get()->GetTabOverlap();
 }
 
 void TabContainerImpl::ResizeLayoutTabs() {
@@ -1535,7 +1535,7 @@
       GetModelIndexOf(tab) ==
           controller_->GetFirstTabInGroup(tab->group().value());
 
-  const int overlap = TabStyle::GetTabOverlap();
+  const int overlap = tab->tab_style()->GetTabOverlap();
   if (!drop_before || !first_in_group || drop_in_group) {
     // Dropping between tabs, or between a group header and the group's first
     // tab.
diff --git a/chrome/browser/ui/views/tabs/tab_container_unittest.cc b/chrome/browser/ui/views/tabs/tab_container_unittest.cc
index 089724c3..0727bea 100644
--- a/chrome/browser/ui/views/tabs/tab_container_unittest.cc
+++ b/chrome/browser/ui/views/tabs/tab_container_unittest.cc
@@ -358,7 +358,7 @@
   AddTab(0, absl::nullopt, TabActive::kActive);
 
   // Create just enough tabs so tabs are not full size.
-  const int standard_width = TabStyleViews::GetStandardWidth();
+  const int standard_width = TabStyle::Get()->GetStandardWidth();
   while (tab_container_->GetActiveTabWidth() == standard_width) {
     AddTab(0);
     tab_container_->CompleteAnimationAndLayout();
@@ -392,7 +392,7 @@
   AddTab(0, absl::nullopt, TabActive::kActive);
 
   // Create enough tabs so tabs are not full size.
-  const int standard_width = TabStyleViews::GetStandardWidth();
+  const int standard_width = TabStyle::Get()->GetStandardWidth();
 
   // Set a tab_counter to avoid infinite loop
   int tab_counter = 0;
@@ -694,7 +694,8 @@
   TabGroupHeader* header = views[0]->header();
   EXPECT_EQ(first_slot_x, header->x());
   EXPECT_GT(header->width(), 0);
-  EXPECT_EQ(header->bounds().right() - TabStyle::GetTabOverlap(), tab->x());
+  EXPECT_EQ(header->bounds().right() - TabStyle::Get()->GetTabOverlap(),
+            tab->x());
   EXPECT_EQ(tab->height(), header->height());
 }
 
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
index afe0351..c380617 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller.cc
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
@@ -2483,7 +2483,7 @@
   // space for the rounded feet. Adding {tab_left_inset} to the horizontal
   // bounds of the tab results in the x position that would be drawn when there
   // are no feet showing.
-  const int tab_left_inset = TabStyle::GetTabOverlap() / 2;
+  const int tab_left_inset = TabStyle::Get()->GetTabOverlap() / 2;
 
   const auto tab_bounds_in_drag_context_coords = [this](int model_index) {
     const Tab* const tab = attached_context_->GetTabAt(model_index);
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
index 2259d1a7..4d8ab29a 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -2777,21 +2777,23 @@
 
   AddTabsAndResetBrowser(browser(), 1);
 
+  const TabStyle* tab_style = TabStyle::Get();
   // We must ensure that we set the bounds of the browser window such that it is
   // wide enough to allow the tab strip to expand to accommodate this tab.
   browser()->window()->SetBounds(
-      gfx::Rect(0, 0, TabStyle::GetStandardWidth() * 5, 400));
+      gfx::Rect(0, 0, tab_style->GetStandardWidth() * 5, 400));
 
   const int tab_strip_width = tab_strip->width();
   const gfx::Point tab_1_center =
       GetCenterInScreenCoordinates(tab_strip->tab_at(1));
   ASSERT_TRUE(PressInput(tab_1_center));
   ASSERT_TRUE(DragInputTo(tab_1_center +
-                          gfx::Vector2d(TabStyle::GetStandardWidth(), 0)));
+                          gfx::Vector2d(tab_style->GetStandardWidth(), 0)));
   BrowserView::GetBrowserViewForBrowser(browser())
       ->GetWidget()
       ->LayoutRootViewIfNecessary();
-  EXPECT_EQ(tab_strip_width + TabStyle::GetStandardWidth(), tab_strip->width());
+  EXPECT_EQ(tab_strip_width + tab_style->GetStandardWidth(),
+            tab_strip->width());
   ASSERT_TRUE(ReleaseInput());
 }
 
diff --git a/chrome/browser/ui/views/tabs/tab_group_header.cc b/chrome/browser/ui/views/tabs/tab_group_header.cc
index 5eb517f..515c47c6 100644
--- a/chrome/browser/ui/views/tabs/tab_group_header.cc
+++ b/chrome/browser/ui/views/tabs/tab_group_header.cc
@@ -108,7 +108,8 @@
               ? SavedTabGroupServiceFactory::GetForProfile(
                     tab_slot_controller_->GetBrowser()->profile())
               : nullptr),
-      style_(style),
+      group_style_(style),
+      tab_style_(TabStyle::Get()),
       editor_bubble_tracker_(tab_slot_controller) {
   set_group(group);
   set_context_menu_controller(this);
@@ -131,8 +132,8 @@
   SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);
   views::FocusRing::Install(this);
   views::HighlightPathGenerator::Install(
-      this, std::make_unique<TabGroupHighlightPathGenerator>(title_chip_,
-                                                             title_, *style_));
+      this, std::make_unique<TabGroupHighlightPathGenerator>(
+                title_chip_, title_, *group_style_));
   // The tab group gets painted with a solid color that may not contrast well
   // with the focus indicator, so draw an outline around the focus ring for it
   // to contrast with the solid color.
@@ -390,7 +391,7 @@
   // The distance from the endge of the view to the tab separator is half of the
   // overlap distance. We should only accept events between the separators.
   gfx::Rect contents_rect = GetLocalBounds();
-  contents_rect.Inset(gfx::Insets::VH(0, TabStyle::GetTabOverlap() / 2));
+  contents_rect.Inset(gfx::Insets::VH(0, tab_style_->GetTabOverlap() / 2));
   return contents_rect.Intersects(rect);
 }
 
@@ -408,7 +409,7 @@
   // during layout however; that would cause an the margin to be visually uneven
   // when the header is in the first slot and thus wouldn't overlap anything to
   // the left.
-  const int overlap_margin = TabStyle::GetTabOverlap() * 2;
+  const int overlap_margin = tab_style_->GetTabOverlap() * 2;
 
   // The empty and non-empty chips have different sizes and corner radii, but
   // both should look nestled against the group stroke of the tab to the right.
@@ -419,7 +420,7 @@
   const std::u16string title =
       tab_slot_controller_->GetGroupTitle(group().value());
   const int right_adjust =
-      style_->GetTitleAdjustmentToTabGroupHeaderDesiredWidth(title);
+      group_style_->GetTitleAdjustmentToTabGroupHeaderDesiredWidth(title);
 
   return overlap_margin + title_chip_->width() + right_adjust;
 }
@@ -437,20 +438,21 @@
   if (ShouldShowSyncIcon()) {
     sync_icon_->SetImage(ui::ImageModel::FromVectorIcon(
         kTabGroupsSyncIcon, color_utils::GetColorWithMaxContrast(color),
-        style_->GetSyncIconWidth()));
+        group_style_->GetSyncIconWidth()));
   }
 
   sync_icon_->SetVisible(ShouldShowSyncIcon());
 
   if (title.empty()) {
-    title_chip_->SetBoundsRect(style_->GetEmptyTitleChipBounds(this));
-    title_chip_->SetBackground(style_->GetEmptyTitleChipBackground(color));
+    title_chip_->SetBoundsRect(group_style_->GetEmptyTitleChipBounds(this));
+    title_chip_->SetBackground(
+        group_style_->GetEmptyTitleChipBackground(color));
 
     if (ShouldShowSyncIcon()) {
       // The `sync_icon` should be centered in the title chip.
       gfx::Rect sync_icon_bounds = title_chip_->GetLocalBounds();
-      sync_icon_bounds.ClampToCenteredSize(
-          gfx::Size(style_->GetSyncIconWidth(), style_->GetSyncIconWidth()));
+      sync_icon_bounds.ClampToCenteredSize(gfx::Size(
+          group_style_->GetSyncIconWidth(), group_style_->GetSyncIconWidth()));
       sync_icon_->SetBoundsRect(sync_icon_bounds);
     } else {
       sync_icon_->SetBounds(0, 0, 0, 0);
@@ -471,7 +473,7 @@
 
     const gfx::Size sync_icon_size =
         ShouldShowSyncIcon()
-            ? gfx::Size(style_->GetSyncIconWidth(), text_height)
+            ? gfx::Size(group_style_->GetSyncIconWidth(), text_height)
             : gfx::Size();
 
     const int padding_between_label_sync_icon =
@@ -480,7 +482,7 @@
     // The max width of the content should be half the standard tab width (not
     // counting overlap).
     const int text_max_width =
-        (TabStyle::GetStandardWidth() - TabStyle::GetTabOverlap()) / 2 -
+        (tab_style_->GetStandardWidth() - tab_style_->GetTabOverlap()) / 2 -
         sync_icon_size.width() - padding_between_label_sync_icon;
 
     const int text_width =
@@ -492,13 +494,14 @@
         text_width + sync_icon_size.width() + padding_between_label_sync_icon;
 
     // horizontal and vertical insets of the title chip.
-    const gfx::Insets title_chip_insets = style_->GetInsetsForHeaderChip();
+    const gfx::Insets title_chip_insets =
+        group_style_->GetInsetsForHeaderChip();
     const int title_chip_vertical_inset = title_chip_insets.top();
     const int title_chip_horizontal_inset = title_chip_insets.left();
 
     // Width of title chip should atleast be the width of an empty title chip.
     const int title_chip_width =
-        std::max(style_->GetEmptyTitleChipBounds(this).width(),
+        std::max(group_style_->GetEmptyTitleChipBounds(this).width(),
                  content_width + 2 * title_chip_horizontal_inset);
 
     // The bounds and background for the `title_chip_` is set here.
@@ -541,9 +544,11 @@
 
 int TabGroupHeader::GetCollapsedHeaderWidth() const {
   const int title_adjustment =
-      style_->GetTitleAdjustmentToTabGroupHeaderDesiredWidth(title_->GetText());
+      group_style_->GetTitleAdjustmentToTabGroupHeaderDesiredWidth(
+          title_->GetText());
   const int title_chip_width = GetTabSizeInfo().standard_width -
-                               2 * TabStyle::GetTabOverlap() - title_adjustment;
+                               2 * tab_style_->GetTabOverlap() -
+                               title_adjustment;
   return title_chip_width + 2 * TabGroupUnderline::GetStrokeInset();
 }
 
diff --git a/chrome/browser/ui/views/tabs/tab_group_header.h b/chrome/browser/ui/views/tabs/tab_group_header.h
index 7a274d8..c3fb780 100644
--- a/chrome/browser/ui/views/tabs/tab_group_header.h
+++ b/chrome/browser/ui/views/tabs/tab_group_header.h
@@ -20,6 +20,7 @@
 class TabSlotController;
 class TabGroupStyle;
 struct TabSizeInfo;
+class TabStyle;
 
 namespace views {
 class ImageView;
@@ -102,7 +103,8 @@
   // Used to verify if this tab group is saved.
   const raw_ptr<SavedTabGroupKeyedService> saved_tab_group_service_;
 
-  const raw_ref<const TabGroupStyle> style_;
+  const raw_ref<const TabGroupStyle> group_style_;
+  const raw_ptr<const TabStyle> tab_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 5e899daf..2a05578 100644
--- a/chrome/browser/ui/views/tabs/tab_group_highlight.cc
+++ b/chrome/browser/ui/views/tabs/tab_group_highlight.cc
@@ -59,7 +59,7 @@
   // which is a well-scoped interaction. A dragging group doesn't nestle in with
   // the tabs around it, so there are no special cases needed when determining
   // its shape.
-  const int corner_radius = TabStyle::GetCornerRadius();
+  const int corner_radius = TabStyle::Get()->GetCornerRadius();
 
   SkPath path;
   path.moveTo(0, bounds().height());
diff --git a/chrome/browser/ui/views/tabs/tab_group_style.cc b/chrome/browser/ui/views/tabs/tab_group_style.cc
index 2ed2e79..67d899c6 100644
--- a/chrome/browser/ui/views/tabs/tab_group_style.cc
+++ b/chrome/browser/ui/views/tabs/tab_group_style.cc
@@ -107,12 +107,13 @@
 }
 
 float TabGroupStyle::GetSelectedTabOpacity() const {
-  return TabStyle::kDefaultSelectedTabOpacity;
+  return TabStyle::Get()->GetSelectedTabOpacity();
 }
 
 // static
 int TabGroupStyle::GetChipCornerRadius() {
-  return TabStyle::GetCornerRadius() - TabGroupUnderline::kStrokeThickness;
+  return TabStyle::Get()->GetCornerRadius() -
+         TabGroupUnderline::kStrokeThickness;
 }
 
 ChromeRefresh2023TabGroupStyle::ChromeRefresh2023TabGroupStyle(
diff --git a/chrome/browser/ui/views/tabs/tab_group_underline.cc b/chrome/browser/ui/views/tabs/tab_group_underline.cc
index 9ed2faf..d1b5a55 100644
--- a/chrome/browser/ui/views/tabs/tab_group_underline.cc
+++ b/chrome/browser/ui/views/tabs/tab_group_underline.cc
@@ -119,7 +119,7 @@
 
 // static
 int TabGroupUnderline::GetStrokeInset() {
-  return TabStyle::GetTabOverlap() + kStrokeThickness;
+  return TabStyle::Get()->GetTabOverlap() + kStrokeThickness;
 }
 
 BEGIN_METADATA(TabGroupUnderline, views::View)
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc
index a0fc180..7e0dc17 100644
--- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc
+++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc
@@ -29,6 +29,7 @@
 #include "chrome/browser/ui/views/chrome_typography.h"
 #include "chrome/browser/ui/views/tabs/tab.h"
 #include "chrome/browser/ui/views/tabs/tab_hover_card_controller.h"
+#include "chrome/browser/ui/views/tabs/tab_style_views.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/url_formatter/url_formatter.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -621,8 +622,8 @@
         break;
       case ImageType::kThumbnail:
         image_view->SetVerticalAlignment(views::ImageView::Alignment::kLeading);
-        image_view->SetImageSize(
-            GetPreviewImageSize(image.size(), TabStyle::GetPreviewImageSize()));
+        image_view->SetImageSize(GetPreviewImageSize(
+            image.size(), bubble_view_->tab_style_->GetPreviewImageSize()));
         image_view->SetBackground(nullptr);
         break;
     }
@@ -632,12 +633,13 @@
   gfx::Size GetMinimumSize() const override { return gfx::Size(); }
 
   gfx::Size CalculatePreferredSize() const override {
-    return image_type_ == ImageType::kNone ? gfx::Size()
-                                           : TabStyle::GetPreviewImageSize();
+    return image_type_ == ImageType::kNone
+               ? gfx::Size()
+               : bubble_view_->tab_style_->GetPreviewImageSize();
   }
 
   gfx::Size GetMaximumSize() const override {
-    return TabStyle::GetPreviewImageSize();
+    return bubble_view_->tab_style_->GetPreviewImageSize();
   }
 
   // views::AnimationDelegateViews:
@@ -733,7 +735,8 @@
 TabHoverCardBubbleView::TabHoverCardBubbleView(Tab* tab)
     : BubbleDialogDelegateView(tab,
                                views::BubbleBorder::TOP_LEFT,
-                               views::BubbleBorder::STANDARD_SHADOW) {
+                               views::BubbleBorder::STANDARD_SHADOW),
+      tab_style_(TabStyle::Get()) {
   SetButtons(ui::DIALOG_BUTTON_NONE);
 
   // Remove the accessible role so that hover cards are not read when they
@@ -988,7 +991,7 @@
 
 gfx::Size TabHoverCardBubbleView::CalculatePreferredSize() const {
   gfx::Size preferred_size = GetLayoutManager()->GetPreferredSize(this);
-  preferred_size.set_width(TabStyle::GetPreviewImageSize().width());
+  preferred_size.set_width(tab_style_->GetPreviewImageSize().width());
   DCHECK(!preferred_size.IsEmpty());
   return preferred_size;
 }
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h
index c8c69f1..36e4106 100644
--- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h
+++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h
@@ -34,6 +34,7 @@
 }
 
 class Tab;
+class TabStyle;
 
 // Dialog that displays an informational hover card containing page information.
 class TabHoverCardBubbleView : public views::BubbleDialogDelegateView {
@@ -150,6 +151,7 @@
   raw_ptr<FadeLabel> domain_label_ = nullptr;
   raw_ptr<ThumbnailView> thumbnail_view_ = nullptr;
   absl::optional<TabAlertState> alert_state_;
+  const raw_ptr<const TabStyle> tab_style_;
 
   int corner_radius_ = ChromeLayoutProvider::Get()->GetCornerRadiusMetric(
       views::Emphasis::kHigh);
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_controller.cc b/chrome/browser/ui/views/tabs/tab_hover_card_controller.cc
index 9e8ec80..77f4beae 100644
--- a/chrome/browser/ui/views/tabs/tab_hover_card_controller.cc
+++ b/chrome/browser/ui/views/tabs/tab_hover_card_controller.cc
@@ -149,7 +149,9 @@
 }
 
 base::TimeDelta GetShowDelay(int tab_width) {
-  static const int max_width_additiona_delay =
+  const TabStyle* tab_style = TabStyle::Get();
+
+  static const int max_width_additional_delay =
       base::GetFieldTrialParamByFeatureAsInt(
           features::kTabHoverCardImages,
           features::kTabHoverCardAdditionalMaxWidthDelay, 500);
@@ -173,17 +175,19 @@
   //               |                                |
   //       pinned tab width               standard tab width
   constexpr base::TimeDelta kMinimumTriggerDelay = base::Milliseconds(300);
-  if (tab_width < TabStyle::GetPinnedWidth())
+  if (tab_width < tab_style->GetPinnedWidth()) {
     return kMinimumTriggerDelay;
+  }
   constexpr base::TimeDelta kMaximumTriggerDelay = base::Milliseconds(800);
   double logarithmic_fraction =
-      std::log(tab_width - TabStyle::GetPinnedWidth() + 1) /
-      std::log(TabStyle::GetStandardWidth() - TabStyle::GetPinnedWidth() + 1);
+      std::log(tab_width - tab_style->GetPinnedWidth() + 1) /
+      std::log(tab_style->GetStandardWidth() - tab_style->GetPinnedWidth() + 1);
   base::TimeDelta scaling_factor = kMaximumTriggerDelay - kMinimumTriggerDelay;
   base::TimeDelta delay =
       logarithmic_fraction * scaling_factor + kMinimumTriggerDelay;
-  if (tab_width >= TabStyle::GetStandardWidth())
-    delay += base::Milliseconds(max_width_additiona_delay);
+  if (tab_width >= tab_style->GetStandardWidth()) {
+    delay += base::Milliseconds(max_width_additional_delay);
+  }
   return delay;
 }
 
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_thumbnail_observer.cc b/chrome/browser/ui/views/tabs/tab_hover_card_thumbnail_observer.cc
index c822ce8..40e44f49d 100644
--- a/chrome/browser/ui/views/tabs/tab_hover_card_thumbnail_observer.cc
+++ b/chrome/browser/ui/views/tabs/tab_hover_card_thumbnail_observer.cc
@@ -18,7 +18,7 @@
     return;
 
   subscription_ = current_image_->Subscribe();
-  subscription_->SetSizeHint(TabStyle::GetPreviewImageSize());
+  subscription_->SetSizeHint(TabStyle::Get()->GetPreviewImageSize());
   subscription_->SetUncompressedImageCallback(base::BindRepeating(
       &TabHoverCardThumbnailObserver::ThumbnailImageCallback,
       base::Unretained(this), base::Unretained(current_image_.get())));
diff --git a/chrome/browser/ui/views/tabs/tab_scrubber_chromeos.cc b/chrome/browser/ui/views/tabs/tab_scrubber_chromeos.cc
index f8e0976..a9cc827 100644
--- a/chrome/browser/ui/views/tabs/tab_scrubber_chromeos.cc
+++ b/chrome/browser/ui/views/tabs/tab_scrubber_chromeos.cc
@@ -62,7 +62,8 @@
   // opposite edges of the tab, which should be at (overlap / 2).
   gfx::Rect tab_edges = tab_bounds;
   // For odd overlap values, be conservative and inset both edges rounding up.
-  tab_edges.Inset(gfx::Insets::VH(0, (TabStyle::GetTabOverlap() + 1) / 2));
+  tab_edges.Inset(
+      gfx::Insets::VH(0, (tab->tab_style()->GetTabOverlap() + 1) / 2));
   const int x = (direction == LEFT)
                     ? std::min(tab_bounds.x() + left, tab_edges.right())
                     : std::max(tab_bounds.right() - right, tab_edges.x());
@@ -91,7 +92,7 @@
                         ui::EventTimeForNow(),
                         /*flags=*/0, x_offset,
                         /*y_offset=*/0.f, /*x_offset_ordinal=*/0.f,
-                        /*y_offset_original=*/0.f, kFingerCount);
+                        /*y_offset_ordinal=*/0.f, kFingerCount);
   OnScrollEvent(&event);
 }
 
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc
index cd8c664..27328ed 100644
--- a/chrome/browser/ui/views/tabs/tab_strip.cc
+++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -66,7 +66,6 @@
 #include "chrome/browser/ui/views/tabs/tab_strip_layout_types.h"
 #include "chrome/browser/ui/views/tabs/tab_strip_observer.h"
 #include "chrome/browser/ui/views/tabs/tab_strip_types.h"
-#include "chrome/browser/ui/views/tabs/tab_style_views.h"
 #include "chrome/browser/ui/views/tabs/z_orderable_tab_container_element.h"
 #include "chrome/browser/ui/views/touch_uma/touch_uma.h"
 #include "chrome/browser/ui/web_applications/app_browser_controller.h"
@@ -452,7 +451,7 @@
     constexpr int kHorizontalMoveThreshold = 16;  // DIPs.
 
     double ratio = static_cast<double>(tab_strip_->GetInactiveTabWidth()) /
-                   TabStyle::GetStandardWidth();
+                   TabStyle::Get()->GetStandardWidth();
     return base::ClampRound(ratio * kHorizontalMoveThreshold);
   }
 
@@ -491,7 +490,7 @@
     DCHECK(!views.empty());
 
     std::vector<gfx::Rect> bounds;
-    const int overlap = TabStyle::GetTabOverlap();
+    const int overlap = TabStyle::Get()->GetTabOverlap();
     int x = 0;
     for (const TabSlotView* view : views) {
       const int width = view->width();
@@ -834,7 +833,7 @@
     if (candidate_index == 0)
       return 0;
 
-    const int tab_overlap = TabStyle::GetTabOverlap();
+    const int tab_overlap = TabStyle::Get()->GetTabOverlap();
 
     // We'll insert just right of the tab at |candidate_index| - 1.
     int ideal_x =
@@ -873,7 +872,7 @@
           return 0;
         const int header_width =
             GetTabGroupHeader(*right_group)->bounds().width() -
-            TabStyle::GetTabOverlap();
+            TabStyle::Get()->GetTabOverlap();
         return header_width;
       }
     }
@@ -910,7 +909,8 @@
           *AddChildViewAt(MakeTabContainer(this,
                                            hover_card_controller_.get(),
                                            base::to_address(drag_context_)),
-                          0)) {
+                          0)),
+      style_(TabStyle::Get()) {
   // TODO(pbos): This is probably incorrect, the background of individual tabs
   // depend on their selected state. This should probably be pushed down into
   // tabs.
@@ -954,7 +954,7 @@
   for (const TabSlotView* view : views)
     width += view->width();
   if (!views.empty())
-    width -= TabStyle::GetTabOverlap() * (views.size() - 1);
+    width -= TabStyle::Get()->GetTabOverlap() * (views.size() - 1);
   return width;
 }
 
diff --git a/chrome/browser/ui/views/tabs/tab_strip.h b/chrome/browser/ui/views/tabs/tab_strip.h
index bae5dee..683accf 100644
--- a/chrome/browser/ui/views/tabs/tab_strip.h
+++ b/chrome/browser/ui/views/tabs/tab_strip.h
@@ -44,6 +44,7 @@
 class TabHoverCardController;
 class TabStripController;
 class TabStripObserver;
+class TabStyle;
 
 namespace gfx {
 class Rect;
@@ -441,6 +442,8 @@
   // Used for seek time metrics from the time the mouse enters the tabstrip.
   absl::optional<base::TimeTicks> mouse_entered_tabstrip_time_;
 
+  const raw_ptr<const TabStyle> style_;
+
   // Number of mouse moves.
   int mouse_move_count_ = 0;
 
diff --git a/chrome/browser/ui/views/tabs/tab_strip_layout_helper.cc b/chrome/browser/ui/views/tabs/tab_strip_layout_helper.cc
index a2c0979..58fae26 100644
--- a/chrome/browser/ui/views/tabs/tab_strip_layout_helper.cc
+++ b/chrome/browser/ui/views/tabs/tab_strip_layout_helper.cc
@@ -33,7 +33,7 @@
 };
 
 TabLayoutConstants GetTabLayoutConstants() {
-  return {GetLayoutConstant(TAB_HEIGHT), TabStyle::GetTabOverlap()};
+  return {GetLayoutConstant(TAB_HEIGHT), TabStyle::Get()->GetTabOverlap()};
 }
 
 }  // namespace
@@ -70,8 +70,8 @@
     GetTabsCallback get_tabs_callback)
     : controller_(controller),
       get_tabs_callback_(get_tabs_callback),
-      active_tab_width_(TabStyle::GetStandardWidth()),
-      inactive_tab_width_(TabStyle::GetStandardWidth()) {}
+      active_tab_width_(TabStyle::Get()->GetStandardWidth()),
+      inactive_tab_width_(TabStyle::Get()->GetStandardWidth()) {}
 
 TabStripLayoutHelper::~TabStripLayoutHelper() = default;
 
diff --git a/chrome/browser/ui/views/tabs/tab_strip_scroll_session.cc b/chrome/browser/ui/views/tabs/tab_strip_scroll_session.cc
index 86c0b625..b462e26 100644
--- a/chrome/browser/ui/views/tabs/tab_strip_scroll_session.cc
+++ b/chrome/browser/ui/views/tabs/tab_strip_scroll_session.cc
@@ -115,7 +115,7 @@
 
 double TabStripScrollSessionWithTimer::CalculateBaseScrollOffset() {
   return kNumberOfTabsScrolledPerSecond *
-         TabStyleViews::GetMinimumInactiveWidth() *
+         TabStyleViews::Create()->GetMinimumInactiveWidth() *
          (kScrollTimerDelay / base::Milliseconds(1000));
 }
 
diff --git a/chrome/browser/ui/views/tabs/tab_strip_scroll_session_unittest.cc b/chrome/browser/ui/views/tabs/tab_strip_scroll_session_unittest.cc
index 63834378..944ef53 100644
--- a/chrome/browser/ui/views/tabs/tab_strip_scroll_session_unittest.cc
+++ b/chrome/browser/ui/views/tabs/tab_strip_scroll_session_unittest.cc
@@ -76,13 +76,13 @@
     scroll_session_->SetTimerForTesting(mock_timer_);
 
     scroll_view_ = std::make_unique<views::ScrollView>();
-    scroll_view_->SetBounds(0, 0, 5 * TabStyleViews::GetMinimumInactiveWidth(),
-                            5);
+    scroll_view_->SetBounds(
+        0, 0, 5 * TabStyleViews::Create()->GetMinimumInactiveWidth(), 5);
 
     attached_context_ =
         scroll_view_->SetContents(std::make_unique<views::View>());
     attached_context_->SetBounds(
-        0, 0, 10 * TabStyleViews::GetMinimumInactiveWidth(), 5);
+        0, 0, 10 * TabStyleViews::Create()->GetMinimumInactiveWidth(), 5);
   }
 
   void TearDown() override { ChromeViewsTestBase::TearDown(); }
diff --git a/chrome/browser/ui/views/tabs/tab_strip_scrolling_overflow_indicator_strategy.cc b/chrome/browser/ui/views/tabs/tab_strip_scrolling_overflow_indicator_strategy.cc
index e41299b1..a02d5172 100644
--- a/chrome/browser/ui/views/tabs/tab_strip_scrolling_overflow_indicator_strategy.cc
+++ b/chrome/browser/ui/views/tabs/tab_strip_scrolling_overflow_indicator_strategy.cc
@@ -208,7 +208,7 @@
           views::OverflowIndicatorAlignment::kRight);
   right_overflow_indicator_ = right_overflow_indicator.get();
 
-  const int min_tab_width = TabStyleViews::GetMinimumInactiveWidth();
+  const int min_tab_width = TabStyleViews::Create()->GetMinimumInactiveWidth();
 
   left_overflow_indicator_->SetShadowBlurWidth(std::min(64, min_tab_width * 2));
   right_overflow_indicator_->SetShadowBlurWidth(
diff --git a/chrome/browser/ui/views/tabs/tab_strip_unittest.cc b/chrome/browser/ui/views/tabs/tab_strip_unittest.cc
index c119117..412e6f3 100644
--- a/chrome/browser/ui/views/tabs/tab_strip_unittest.cc
+++ b/chrome/browser/ui/views/tabs/tab_strip_unittest.cc
@@ -408,7 +408,7 @@
   controller_->AddTab(1, TabActive::kActive);
   controller_->AddTab(2, TabActive::kInactive);
 
-  const int standard_width = TabStyle::GetStandardWidth();
+  const int standard_width = TabStyle::Get()->GetStandardWidth();
 
   SetMaxTabStripWidth(1000);
 
@@ -422,8 +422,10 @@
 
   SetMaxTabStripWidth(50);
 
-  EXPECT_EQ(TabStyleViews::GetMinimumActiveWidth(), GetActiveTabWidth());
-  EXPECT_EQ(TabStyleViews::GetMinimumInactiveWidth(), GetInactiveTabWidth());
+  EXPECT_EQ(TabStyleViews::Create()->GetMinimumActiveWidth(),
+            GetActiveTabWidth());
+  EXPECT_EQ(TabStyleViews::Create()->GetMinimumInactiveWidth(),
+            GetInactiveTabWidth());
 }
 
 // The active tab should always be at least as wide as its minimum width.
@@ -435,7 +437,8 @@
   SetMaxTabStripWidth(400);
 
   // Create a lot of tabs in order to make inactive tabs tiny.
-  const int min_inactive_width = TabStyleViews::GetMinimumInactiveWidth();
+  const int min_inactive_width =
+      TabStyleViews::Create()->GetMinimumInactiveWidth();
   while (GetInactiveTabWidth() != min_inactive_width) {
     controller_->CreateNewTab();
     CompleteAnimationAndLayout();
@@ -454,7 +457,7 @@
   while (tab_strip_->GetTabCount() > 0) {
     active_index = tab_strip_->GetActiveIndex().value();
     EXPECT_GE(tab_strip_->tab_at(active_index)->bounds().width(),
-              TabStyleViews::GetMinimumActiveWidth());
+              TabStyleViews::Create()->GetMinimumActiveWidth());
     tab_strip_->CloseTab(tab_strip_->tab_at(active_index),
                          CLOSE_TAB_FROM_MOUSE);
     CompleteAnimationAndLayout();
@@ -468,8 +471,9 @@
 
   // Create a lot of tabs in order to make inactive tabs smaller than active
   // tab but not the minimum.
-  const int min_inactive_width = TabStyleViews::GetMinimumInactiveWidth();
-  const int min_active_width = TabStyleViews::GetMinimumActiveWidth();
+  const int min_inactive_width =
+      TabStyleViews::Create()->GetMinimumInactiveWidth();
+  const int min_active_width = TabStyleViews::Create()->GetMinimumActiveWidth();
   while (GetInactiveTabWidth() >= (min_inactive_width + min_active_width) / 2) {
     controller_->CreateNewTab();
     CompleteAnimationAndLayout();
@@ -497,13 +501,14 @@
   SetMaxTabStripWidth(200);
 
   // Create a lot of tabs in order to make inactive tabs tiny.
-  const int min_inactive_width = TabStyleViews::GetMinimumInactiveWidth();
+  const int min_inactive_width =
+      TabStyleViews::Create()->GetMinimumInactiveWidth();
   while (GetInactiveTabWidth() != min_inactive_width) {
     controller_->CreateNewTab();
     CompleteAnimationAndLayout();
   }
 
-  const int min_active_width = TabStyleViews::GetMinimumActiveWidth();
+  const int min_active_width = TabStyleViews::Create()->GetMinimumActiveWidth();
 
   int dragged_tab_index = tab_strip_->GetActiveIndex().value();
   ASSERT_GE(tab_strip_->tab_at(dragged_tab_index)->bounds().width(),
diff --git a/chrome/browser/ui/views/tabs/tab_style_views.cc b/chrome/browser/ui/views/tabs/tab_style_views.cc
index 221f622..0dabeae 100644
--- a/chrome/browser/ui/views/tabs/tab_style_views.cc
+++ b/chrome/browser/ui/views/tabs/tab_style_views.cc
@@ -86,21 +86,20 @@
 
  protected:
   // TabStyle:
-  SkPath GetPath(
-      PathType path_type,
-      float scale,
-      bool force_active = false,
-      RenderUnits render_units = RenderUnits::kPixels) const override;
+  SkPath GetPath(TabStyle::PathType path_type,
+                 float scale,
+                 bool force_active = false,
+                 TabStyle::RenderUnits render_units =
+                     TabStyle::RenderUnits::kPixels) const override;
   gfx::Insets GetContentsInsets() const override;
   float GetZValue() const override;
   float GetActiveOpacity() const override;
   TabActive GetApparentActiveState() const override;
   TabStyle::TabColors CalculateColors() const override;
-  float GetSelectedTabOpacity() const override;
   void PaintTab(gfx::Canvas* canvas) const override;
   void SetHoverLocation(const gfx::Point& location) override;
-  void ShowHover(ShowHoverStyle style) override;
-  void HideHover(HideHoverStyle style) override;
+  void ShowHover(TabStyle::ShowHoverStyle style) override;
+  void HideHover(TabStyle::HideHoverStyle style) override;
 
   // Painting helper functions:
   virtual SkColor GetTabBackgroundColor(TabActive active) const;
@@ -113,12 +112,12 @@
 
  private:
   // Gets the bounds for the leading and trailing separators for a tab.
-  SeparatorBounds GetSeparatorBounds(float scale) const;
+  TabStyle::SeparatorBounds GetSeparatorBounds(float scale) const;
 
   // Returns the opacities of the separators. If |for_layout| is true, returns
   // the "layout" opacities, which ignore the effects of surrounding tabs' hover
   // effects and consider only the current tab's state.
-  SeparatorOpacities GetSeparatorOpacities(bool for_layout) const;
+  TabStyle::SeparatorOpacities GetSeparatorOpacities(bool for_layout) const;
 
   // Returns a single separator's opacity based on whether it is the
   // logically |leading| separator. |for_layout| has the same meaning as in
@@ -155,7 +154,7 @@
   // there are anti-aliasing artifacts in the overlapped lower arc region. This
   // returns how to modify the tab shape to eliminate the lower arcs on the
   // right or left based on the state of the adjacent tab(s).
-  ShapeModifier GetShapeModifier(PathType path_type) const;
+  ShapeModifier GetShapeModifier(TabStyle::PathType path_type) const;
 
   // Painting helper functions:
   void PaintInactiveTabBackground(gfx::Canvas* canvas) const;
@@ -174,13 +173,13 @@
   void PaintSeparators(gfx::Canvas* canvas) const;
 
   // Given a tab of width |width|, returns the radius to use for the corners.
-  static float GetTopCornerRadiusForWidth(int width);
+  float GetTopCornerRadiusForWidth(int width) const;
 
   // Scales |bounds| by scale and aligns so that adjacent tabs meet up exactly
   // during painting.
-  static gfx::RectF ScaleAndAlignBounds(const gfx::Rect& bounds,
-                                        float scale,
-                                        int stroke_thickness);
+  gfx::RectF ScaleAndAlignBounds(const gfx::Rect& bounds,
+                                 float scale,
+                                 int stroke_thickness) const;
 
   const raw_ptr<const Tab> tab_;
 
@@ -198,10 +197,10 @@
   // repurposing CONTEXT_BUTTON_MD.
 }
 
-SkPath GM2TabStyle::GetPath(PathType path_type,
+SkPath GM2TabStyle::GetPath(TabStyle::PathType path_type,
                             float scale,
                             bool force_active,
-                            RenderUnits render_units) const {
+                            TabStyle::RenderUnits render_units) const {
   CHECK(tab());
   const int stroke_thickness = GetStrokeThickness(force_active);
 
@@ -211,7 +210,7 @@
   gfx::RectF aligned_bounds =
       ScaleAndAlignBounds(tab_->bounds(), scale, stroke_thickness);
 
-  if (path_type == PathType::kInteriorClip) {
+  if (path_type == TabStyle::PathType::kInteriorClip) {
     // When there is a separator, animate the clip to account for it, in sync
     // with the separator's fading.
     // TODO(pkasting): Consider crossfading the favicon instead of animating
@@ -250,20 +249,21 @@
   // Path-specific adjustments:
   const float stroke_adjustment = stroke_thickness * scale;
   bool extend_to_top = false;
-  if (path_type == PathType::kInteriorClip) {
+  if (path_type == TabStyle::PathType::kInteriorClip) {
     // Inside of the border runs |stroke_thickness| inside the outer edge.
     tab_left += stroke_adjustment;
     tab_right -= stroke_adjustment;
     tab_top += stroke_adjustment;
     top_radius -= stroke_adjustment;
-  } else if (path_type == PathType::kFill || path_type == PathType::kBorder) {
+  } else if (path_type == TabStyle::PathType::kFill ||
+             path_type == TabStyle::PathType::kBorder) {
     tab_left += 0.5f * stroke_adjustment;
     tab_right -= 0.5f * stroke_adjustment;
     tab_top += 0.5f * stroke_adjustment;
     top_radius -= 0.5f * stroke_adjustment;
     tab_bottom -= 0.5f * stroke_adjustment;
     bottom_radius -= 0.5f * stroke_adjustment;
-  } else if (path_type == PathType::kHitTest) {
+  } else if (path_type == TabStyle::PathType::kHitTest) {
     // Outside border needs to draw its bottom line a stroke width above the
     // bottom of the tab, to line up with the stroke that runs across the rest
     // of the bottom of the tab bar (when strokes are enabled).
@@ -287,10 +287,10 @@
 
   SkPath path;
 
-  if (path_type == PathType::kInteriorClip) {
+  if (path_type == TabStyle::PathType::kInteriorClip) {
     // Clip path is a simple rectangle.
     path.addRect(tab_left, tab_top, tab_right, tab_bottom);
-  } else if (path_type == PathType::kHighlight) {
+  } else if (path_type == TabStyle::PathType::kHighlight) {
     // The path is a round rect inset by the focus ring thickness. The
     // radius is also adjusted by the inset.
     const float inset = views::FocusRing::kDefaultHaloThickness +
@@ -392,8 +392,9 @@
     // ┌─╯         ╰─┓
     path.lineTo(right, extended_bottom);
 
-    if (path_type != PathType::kBorder)
+    if (path_type != TabStyle::PathType::kBorder) {
       path.close();
+    }
   }
 
   // Convert path to be relative to the tab origin.
@@ -402,8 +403,9 @@
   path.offset(-origin.x(), -origin.y());
 
   // Possibly convert back to DIPs.
-  if (render_units == RenderUnits::kDips && scale != 1.0f)
+  if (render_units == TabStyle::RenderUnits::kDips && scale != 1.0f) {
     path.transform(SkMatrix::Scale(1.0f / scale, 1.0f / scale));
+  }
 
   return path;
 }
@@ -489,10 +491,6 @@
           close_button_focus_ring_color};
 }
 
-float GM2TabStyle::GetSelectedTabOpacity() const {
-  return kDefaultSelectedTabOpacity;
-}
-
 void GM2TabStyle::PaintTab(gfx::Canvas* canvas) const {
   CHECK(tab());
   absl::optional<int> active_tab_fill_id;
@@ -528,19 +526,19 @@
     hover_controller_->SetLocation(location);
 }
 
-void GM2TabStyle::ShowHover(ShowHoverStyle style) {
+void GM2TabStyle::ShowHover(TabStyle::ShowHoverStyle style) {
   CHECK(tab());
   if (!hover_controller_)
     return;
 
-  if (style == ShowHoverStyle::kSubtle) {
+  if (style == TabStyle::ShowHoverStyle::kSubtle) {
     hover_controller_->SetSubtleOpacityScale(
         tab_->controller()->GetHoverOpacityForRadialHighlight());
   }
   hover_controller_->Show(style);
 }
 
-void GM2TabStyle::HideHover(HideHoverStyle style) {
+void GM2TabStyle::HideHover(TabStyle::HideHoverStyle style) {
   CHECK(tab());
   if (hover_controller_)
     hover_controller_->Hide(style);
@@ -554,7 +552,7 @@
   gfx::SizeF separator_size(GetSeparatorSize());
   separator_size.Scale(scale);
 
-  SeparatorBounds separator_bounds;
+  TabStyle::SeparatorBounds separator_bounds;
 
   separator_bounds.leading =
       gfx::RectF(aligned_bounds.x() + corner_radius,
@@ -787,11 +785,12 @@
   return color;
 }
 
-ShapeModifier GM2TabStyle::GetShapeModifier(PathType path_type) const {
+ShapeModifier GM2TabStyle::GetShapeModifier(
+    TabStyle::PathType path_type) const {
   CHECK(tab());
   ShapeModifier shape_modifier = kNone;
-  if (path_type == PathType::kFill && tab_->IsSelected() && !IsHoverActive() &&
-      !tab_->IsActive()) {
+  if (path_type == TabStyle::PathType::kFill && tab_->IsSelected() &&
+      !IsHoverActive() && !tab_->IsActive()) {
     auto check_adjacent_tab = [](const Tab* tab, int offset,
                                  ShapeModifier modifier) {
       const Tab* adjacent_tab = tab->controller()->GetAdjacentTab(tab, offset);
@@ -845,8 +844,9 @@
                                          absl::optional<int> fill_id,
                                          int y_inset) const {
   CHECK(tab());
-  const SkPath fill_path = GetPath(PathType::kFill, canvas->image_scale(),
-                                   active == TabActive::kActive);
+  const SkPath fill_path =
+      GetPath(TabStyle::PathType::kFill, canvas->image_scale(),
+              active == TabActive::kActive);
   gfx::ScopedCanvas scoped_canvas(canvas);
   const float scale = canvas->UndoDeviceScaleFactor();
 
@@ -928,8 +928,7 @@
   canvas->DrawRect(separator_bounds.trailing, flags);
 }
 
-// static
-float GM2TabStyle::GetTopCornerRadiusForWidth(int width) {
+float GM2TabStyle::GetTopCornerRadiusForWidth(int width) const {
   // Get the width of the top of the tab by subtracting the width of the outer
   // corners.
   const int ideal_radius = GetCornerRadius();
@@ -941,10 +940,9 @@
   return std::clamp<float>(radius, 0, ideal_radius);
 }
 
-// static
 gfx::RectF GM2TabStyle::ScaleAndAlignBounds(const gfx::Rect& bounds,
                                             float scale,
-                                            int stroke_thickness) {
+                                            int stroke_thickness) const {
   // Convert to layout bounds.  We must inset the width such that the right edge
   // of one tab's layout bounds is the same as the left edge of the next tab's;
   // this way the two tabs' separators will be drawn at the same coordinate.
@@ -1069,12 +1067,12 @@
   return std::make_unique<GM2TabStyle>(tab);
 }
 
+// static
 std::unique_ptr<TabStyleViews> TabStyleViews::Create() {
   return TabStyleViews::CreateForTab(nullptr);
 }
 
-// static
-int TabStyleViews::GetMinimumActiveWidth() {
+int TabStyleViews::GetMinimumActiveWidth() const {
   int min_active_width =
       TabCloseButton::GetGlyphSize() + GetContentsHorizontalInsetSize() * 2;
   if (base::FeatureList::IsEnabled(features::kScrollableTabStrip)) {
@@ -1087,8 +1085,7 @@
   return min_active_width;
 }
 
-// static
-int TabStyleViews::GetMinimumInactiveWidth() {
+int TabStyleViews::GetMinimumInactiveWidth() const {
   // Allow tabs to shrink until they appear to be 16 DIP wide excluding
   // outer corners.
   constexpr int kInteriorWidth = 16;
diff --git a/chrome/browser/ui/views/tabs/tab_style_views.h b/chrome/browser/ui/views/tabs/tab_style_views.h
index 46cc79db..d4d94e5 100644
--- a/chrome/browser/ui/views/tabs/tab_style_views.h
+++ b/chrome/browser/ui/views/tabs/tab_style_views.h
@@ -42,11 +42,11 @@
   // If |force_active| is true, applies an active appearance on the tab (usually
   // involving painting an optional stroke) even if the tab is not the active
   //  tab.
-  virtual SkPath GetPath(
-      PathType path_type,
-      float scale,
-      bool force_active = false,
-      RenderUnits render_units = RenderUnits::kPixels) const = 0;
+  virtual SkPath GetPath(TabStyle::PathType path_type,
+                         float scale,
+                         bool force_active = false,
+                         TabStyle::RenderUnits render_units =
+                             TabStyle::RenderUnits::kPixels) const = 0;
 
   // Paints the tab.
   virtual void PaintTab(gfx::Canvas* canvas) const = 0;
@@ -67,27 +67,24 @@
   virtual float GetActiveOpacity() const = 0;
 
   // Derives and returns colors for the tab. See TabColors, above.
-  virtual TabColors CalculateColors() const = 0;
-
-  // Opacity of the active tab background painted over inactive selected tabs.
-  virtual float GetSelectedTabOpacity() const = 0;
+  virtual TabStyle::TabColors CalculateColors() const = 0;
 
   // Sets the center of the radial highlight in the hover animation.
   virtual void SetHoverLocation(const gfx::Point& location) = 0;
 
   // Shows the hover animation.
-  virtual void ShowHover(ShowHoverStyle style) = 0;
+  virtual void ShowHover(TabStyle::ShowHoverStyle style) = 0;
 
   // Hides the hover animation.
-  virtual void HideHover(HideHoverStyle style) = 0;
+  virtual void HideHover(TabStyle::HideHoverStyle style) = 0;
 
   // Returns the minimum possible width of a selected Tab. Selected tabs must
   // always show a close button, and thus have a larger minimum size than
   // unselected tabs.
-  static int GetMinimumActiveWidth();
+  int GetMinimumActiveWidth() const;
 
   // Returns the minimum possible width of a single unselected Tab.
-  static int GetMinimumInactiveWidth();
+  int GetMinimumInactiveWidth() const;
 
  protected:
   // Avoid implicitly-deleted constructor.
diff --git a/chrome/browser/ui/views/tabs/tab_unittest.cc b/chrome/browser/ui/views/tabs/tab_unittest.cc
index d266038..3d635cc7 100644
--- a/chrome/browser/ui/views/tabs/tab_unittest.cc
+++ b/chrome/browser/ui/views/tabs/tab_unittest.cc
@@ -349,11 +349,12 @@
         // Test layout for every width from standard to minimum.
         int width, min_width;
         if (is_pinned_tab) {
-          width = min_width = TabStyle::GetPinnedWidth();
+          width = min_width = tab->tab_style()->GetPinnedWidth();
         } else {
-          width = TabStyle::GetStandardWidth();
-          min_width = is_active_tab ? TabStyleViews::GetMinimumActiveWidth()
-                                    : TabStyleViews::GetMinimumInactiveWidth();
+          width = tab->tab_style()->GetStandardWidth();
+          min_width = is_active_tab
+                          ? tab->tab_style()->GetMinimumActiveWidth()
+                          : tab->tab_style()->GetMinimumInactiveWidth();
         }
         const int height = GetLayoutConstant(TAB_HEIGHT);
         for (; width >= min_width; --width) {
diff --git a/chrome/browser/ui/views/toolbar/browser_app_menu_button.cc b/chrome/browser/ui/views/toolbar/browser_app_menu_button.cc
index 07cf9063..64da8b20 100644
--- a/chrome/browser/ui/views/toolbar/browser_app_menu_button.cc
+++ b/chrome/browser/ui/views/toolbar/browser_app_menu_button.cc
@@ -6,6 +6,7 @@
 
 #include <set>
 
+#include "base/feature_list.h"
 #include "base/functional/bind.h"
 #include "base/location.h"
 #include "base/task/single_thread_task_runner.h"
@@ -18,6 +19,7 @@
 #include "chrome/browser/ui/color/chrome_color_id.h"
 #include "chrome/browser/ui/layout_constants.h"
 #include "chrome/browser/ui/toolbar/app_menu_model.h"
+#include "chrome/browser/ui/ui_features.h"
 #include "chrome/browser/ui/views/chrome_layout_provider.h"
 #include "chrome/browser/ui/views/toolbar/app_menu.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_ink_drop_util.h"
@@ -151,7 +153,22 @@
   } else if (type_and_severity_.type ==
              AppMenuIconController::IconType::UPGRADE_NOTIFICATION) {
     tooltip_message_id = IDS_APPMENU_TOOLTIP_UPDATE_AVAILABLE;
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING) && \
+    (BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX))
+    int message_id = IDS_APP_MENU_BUTTON_UPDATE;
+    if (base::FeatureList::IsEnabled(features::kUpdateTextOptions)) {
+      if (features::kUpdateTextOptionNumber.Get() == 1) {
+        message_id = IDS_APP_MENU_BUTTON_UPDATE_ALT1;
+      } else if (features::kUpdateTextOptionNumber.Get() == 2) {
+        message_id = IDS_APP_MENU_BUTTON_UPDATE_ALT2;
+      } else {
+        message_id = IDS_APP_MENU_BUTTON_UPDATE_ALT3;
+      }
+    }
+    text = l10n_util::GetStringUTF16(message_id);
+#else
     text = l10n_util::GetStringUTF16(IDS_APP_MENU_BUTTON_UPDATE);
+#endif
   } else {
     tooltip_message_id = IDS_APPMENU_TOOLTIP_ALERT;
     text = l10n_util::GetStringUTF16(IDS_APP_MENU_BUTTON_ERROR);
diff --git a/chrome/browser/ui/views/toolbar/toolbar_button.cc b/chrome/browser/ui/views/toolbar/toolbar_button.cc
index 485d96c..1340622 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_button.cc
+++ b/chrome/browser/ui/views/toolbar/toolbar_button.cc
@@ -205,6 +205,7 @@
   SetProperty(views::kInternalPaddingKey, gfx::Insets());
 
   SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);
+  views::FocusRing::Get(this)->SetOutsetFocusRingDisabled(true);
 }
 
 ToolbarButton::~ToolbarButton() = default;
diff --git a/chrome/browser/ui/views/translate/translate_icon_view.cc b/chrome/browser/ui/views/translate/translate_icon_view.cc
index 7478c00..f4931d4 100644
--- a/chrome/browser/ui/views/translate/translate_icon_view.cc
+++ b/chrome/browser/ui/views/translate/translate_icon_view.cc
@@ -15,6 +15,7 @@
 #include "chrome/browser/ui/views/translate/translate_bubble_controller.h"
 #include "chrome/browser/ui/views/translate/translate_bubble_view.h"
 #include "chrome/grit/generated_resources.h"
+#include "components/omnibox/browser/omnibox_field_trial.h"
 #include "components/translate/core/browser/language_state.h"
 #include "components/translate/core/browser/translate_manager.h"
 #include "components/translate/core/browser/translate_metrics_logger.h"
@@ -97,7 +98,9 @@
     PageActionIconView::ExecuteSource execute_source) {}
 
 const gfx::VectorIcon& TranslateIconView::GetVectorIcon() const {
-  return kTranslateIcon;
+  return OmniboxFieldTrial::IsChromeRefreshIconsEnabled()
+             ? kTranslateChromeRefreshIcon
+             : kTranslateIcon;
 }
 
 BEGIN_METADATA(TranslateIconView, PageActionIconView)
diff --git a/chrome/browser/ui/views/update_recommended_message_box.cc b/chrome/browser/ui/views/update_recommended_message_box.cc
index 0f21fe5f..366dfdf3 100644
--- a/chrome/browser/ui/views/update_recommended_message_box.cc
+++ b/chrome/browser/ui/views/update_recommended_message_box.cc
@@ -4,11 +4,13 @@
 
 #include "chrome/browser/ui/views/update_recommended_message_box.h"
 
+#include "base/feature_list.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/ui_features.h"
 #include "chrome/browser/ui/views/chrome_layout_provider.h"
 #include "chrome/grit/chromium_strings.h"
 #include "components/constrained_window/constrained_window_views.h"
@@ -37,10 +39,26 @@
                  l10n_util::GetStringUTF16(IDS_NOT_NOW));
   SetModalType(ui::MODAL_TYPE_WINDOW);
   SetOwnedByWidget(true);
+
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING) && \
+    (BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX))
+  SetTitle(base::FeatureList::IsEnabled(features::kUpdateTextOptions)
+               ? IDS_UPDATE_RECOMMENDED_DIALOG_TITLE_ALT
+               : IDS_UPDATE_RECOMMENDED_DIALOG_TITLE);
+#else
   SetTitle(IDS_UPDATE_RECOMMENDED_DIALOG_TITLE);
+#endif
+
   std::u16string update_message;
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   update_message = l10n_util::GetStringUTF16(IDS_UPDATE_RECOMMENDED);
+#elif BUILDFLAG(GOOGLE_CHROME_BRANDING) && \
+    (BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX))
+  update_message = l10n_util::GetPluralStringFUTF16(
+      base::FeatureList::IsEnabled(features::kUpdateTextOptions)
+          ? IDS_UPDATE_RECOMMENDED_ALT
+          : IDS_UPDATE_RECOMMENDED,
+      BrowserList::GetIncognitoBrowserCount());
 #else
   update_message = l10n_util::GetPluralStringFUTF16(
       IDS_UPDATE_RECOMMENDED, BrowserList::GetIncognitoBrowserCount());
diff --git a/chrome/browser/ui/views/user_education/browser_feature_promo_controller.cc b/chrome/browser/ui/views/user_education/browser_feature_promo_controller.cc
index c232cee..a1b9901 100644
--- a/chrome/browser/ui/views/user_education/browser_feature_promo_controller.cc
+++ b/chrome/browser/ui/views/user_education/browser_feature_promo_controller.cc
@@ -97,7 +97,17 @@
 #else
   static const auto kAccelerator = IDC_FOCUS_NEXT_PANE;
 #endif
-  CHECK(browser_view_->GetAccelerator(kAccelerator, &accelerator));
+  if (browser_view_->GetAccelerator(kAccelerator, &accelerator)) {
+    accelerator_text = accelerator.GetShortcutText();
+  } else {
+    // TODO(crbug.com/1432803): GetAccelerator appears to be failing
+    // sporadically on Windows, for unknown reasons. Since we can't have this
+    // code crashing in release, it's being returned to the original NOTREACHED
+    // before everything was changed to CHECKs. This bug will continue to be
+    // researched for a more correct fix.
+    accelerator_text = u"F6";
+    NOTREACHED();
+  }
   return l10n_util::GetStringFUTF16(IDS_FOCUS_HELP_BUBBLE_TUTORIAL_DESCRIPTION,
                                     accelerator.GetShortcutText());
 }
diff --git a/chrome/browser/ui/views/user_education/browser_user_education_service.cc b/chrome/browser/ui/views/user_education/browser_user_education_service.cc
index 19675e11..f4df27ba 100644
--- a/chrome/browser/ui/views/user_education/browser_user_education_service.cc
+++ b/chrome/browser/ui/views/user_education/browser_user_education_service.cc
@@ -392,25 +392,6 @@
           .SetBubbleTitleText(IDS_BATTERY_SAVER_MODE_PROMO_TITLE)
           .SetBubbleArrow(HelpBubbleArrow::kTopRight)));
 
-  // kIPHHighEfficiencyInfoModeFeature:
-  registry.RegisterFeature(std::move(
-      FeaturePromoSpecification::CreateForCustomAction(
-          feature_engagement::kIPHHighEfficiencyInfoModeFeature,
-          kHighEfficiencyChipElementId,
-          IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TEXT,
-          IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_ACTION_TEXT,
-          base::BindRepeating(
-              [](ui::ElementContext ctx,
-                 user_education::FeaturePromoHandle promo_handle) {
-                auto* browser = chrome::FindBrowserWithUiElementContext(ctx);
-                if (browser)
-                  chrome::ShowSettingsSubPage(browser,
-                                              chrome::kPerformanceSubPage);
-                RecordHighEfficiencyInfoIPHOpenSettings(browser != nullptr);
-              }))
-          .SetBubbleTitleText(IDS_HIGH_EFFICIENCY_INFO_MODE_PROMO_TITLE)
-          .SetBubbleArrow(HelpBubbleArrow::kTopCenter)));
-
   // kIPHHighEfficiencyModeFeature:
   registry.RegisterFeature(std::move(
       FeaturePromoSpecification::CreateForCustomAction(
diff --git a/chrome/browser/ui/views/web_apps/web_app_tab_strip_browsertest.cc b/chrome/browser/ui/views/web_apps/web_app_tab_strip_browsertest.cc
index 4264a5a0..2920935 100644
--- a/chrome/browser/ui/views/web_apps/web_app_tab_strip_browsertest.cc
+++ b/chrome/browser/ui/views/web_apps/web_app_tab_strip_browsertest.cc
@@ -20,6 +20,7 @@
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/location_bar/custom_tab_bar_view.h"
 #include "chrome/browser/ui/views/tabs/tab_strip.h"
+#include "chrome/browser/ui/views/tabs/tab_strip_controller.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
 #include "chrome/browser/ui/web_applications/app_browser_controller.h"
 #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
@@ -775,4 +776,40 @@
   EXPECT_FALSE(commandController->IsCommandEnabled(IDC_CLOSE_TAB));
 }
 
+IN_PROC_BROWSER_TEST_F(WebAppTabStripBrowserTest,
+                       MiddleClickDoesntCloseHomeTab) {
+  GURL start_url =
+      embedded_test_server()->GetURL("/web_apps/tab_strip_customizations.html");
+  AppId app_id = InstallWebAppFromPage(browser(), start_url);
+  Browser* app_browser = FindWebAppBrowser(browser()->profile(), app_id);
+  TabStripModel* tab_strip_model = app_browser->tab_strip_model();
+
+  EXPECT_TRUE(registrar().IsTabbedWindowModeEnabled(app_id));
+
+  // Expect app opened with pinned home tab.
+  EXPECT_EQ(tab_strip_model->count(), 1);
+  EXPECT_TRUE(tab_strip_model->IsTabPinned(0));
+  EXPECT_EQ(tab_strip_model->GetWebContentsAt(0)->GetVisibleURL(), start_url);
+  EXPECT_EQ(tab_strip_model->active_index(), 0);
+
+  BrowserView* view = BrowserView::GetBrowserViewForBrowser(app_browser);
+  TabStripController* controller = view->tabstrip()->controller();
+
+  // The home tab is the only tab open so it can be closed.
+  EXPECT_TRUE(
+      controller->BeforeCloseTab(0, CloseTabSource::CLOSE_TAB_FROM_MOUSE));
+
+  // Open another tab.
+  OpenUrlAndWait(app_browser,
+                 embedded_test_server()->GetURL("/web_apps/get_manifest.html"));
+  EXPECT_EQ(tab_strip_model->count(), 2);
+
+  // Home tab should not be closable.
+  EXPECT_FALSE(
+      controller->BeforeCloseTab(0, CloseTabSource::CLOSE_TAB_FROM_MOUSE));
+  // Non home tab should be closable.
+  EXPECT_TRUE(
+      controller->BeforeCloseTab(1, CloseTabSource::CLOSE_TAB_FROM_MOUSE));
+}
+
 }  // namespace web_app
diff --git a/chrome/browser/ui/web_applications/web_app_tabbed_utils.cc b/chrome/browser/ui/web_applications/web_app_tabbed_utils.cc
index c47f6c865..573aed9 100644
--- a/chrome/browser/ui/web_applications/web_app_tabbed_utils.cc
+++ b/chrome/browser/ui/web_applications/web_app_tabbed_utils.cc
@@ -4,17 +4,19 @@
 
 #include "chrome/browser/ui/web_applications/web_app_tabbed_utils.h"
 
+#include "chrome/browser/ui/tabs/tab_strip_model_delegate.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace web_app {
 
-bool HasPinnedHomeTab(TabStripModel* tab_strip_model) {
+bool HasPinnedHomeTab(const TabStripModel* tab_strip_model) {
   if (!tab_strip_model->ContainsIndex(0))
     return false;
-  return tab_strip_model->IsTabPinned(0);
+  return tab_strip_model->delegate()->IsForWebApp() &&
+         tab_strip_model->IsTabPinned(0);
 }
 
-bool IsPinnedHomeTab(TabStripModel* tab_strip_model, int index) {
+bool IsPinnedHomeTab(const TabStripModel* tab_strip_model, int index) {
   return HasPinnedHomeTab(tab_strip_model) && index == 0;
 }
 
diff --git a/chrome/browser/ui/web_applications/web_app_tabbed_utils.h b/chrome/browser/ui/web_applications/web_app_tabbed_utils.h
index 6b5b785..d9a1e8a 100644
--- a/chrome/browser/ui/web_applications/web_app_tabbed_utils.h
+++ b/chrome/browser/ui/web_applications/web_app_tabbed_utils.h
@@ -13,10 +13,10 @@
 namespace web_app {
 
 // Returns whether the web apps tab strip contains a pinned home tab.
-bool HasPinnedHomeTab(TabStripModel* tab_strip_model);
+bool HasPinnedHomeTab(const TabStripModel* tab_strip_model);
 
 // Returns whether the tab at the given index is the pinned home tab.
-bool IsPinnedHomeTab(TabStripModel* tab_strip_model, int index);
+bool IsPinnedHomeTab(const TabStripModel* tab_strip_model, int index);
 
 // Returns whether the given launch_url should be treated as the home tab URL.
 bool IsPinnedHomeTabUrl(const WebAppRegistrar& registrar,
diff --git a/chrome/browser/ui/webui/ash/internet_detail_dialog.cc b/chrome/browser/ui/webui/ash/internet_detail_dialog.cc
index d55668b..c2ed4c4 100644
--- a/chrome/browser/ui/webui/ash/internet_detail_dialog.cc
+++ b/chrome/browser/ui/webui/ash/internet_detail_dialog.cc
@@ -22,6 +22,7 @@
 #include "chromeos/ash/components/network/network_state.h"
 #include "chromeos/ash/components/network/network_state_handler.h"
 #include "chromeos/ash/components/network/network_util.h"
+#include "chromeos/constants/chromeos_features.h"
 #include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h"
 #include "chromeos/strings/grit/chromeos_strings.h"
 #include "components/strings/grit/components_strings.h"
@@ -31,6 +32,7 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/chromeos/strings/grit/ui_chromeos_strings.h"
 #include "ui/chromeos/strings/network/network_element_localized_strings_provider.h"
+#include "ui/webui/color_change_listener/color_change_handler.h"
 
 namespace ash {
 
@@ -173,6 +175,7 @@
   source->AddBoolean("showTechnologyBadge",
                      !features::IsSeparateNetworkIconsEnabled());
   source->AddBoolean("apnRevamp", features::IsApnRevampEnabled());
+  source->AddBoolean("isJellyEnabled", chromeos::features::IsJellyEnabled());
   cellular_setup::AddNonStringLoadTimeData(source);
   AddInternetStrings(source);
   source->AddLocalizedString("title", IDS_SETTINGS_INTERNET_DETAIL);
@@ -193,6 +196,12 @@
   GetNetworkConfigService(std::move(receiver));
 }
 
+void InternetDetailDialogUI::BindInterface(
+    mojo::PendingReceiver<color_change_listener::mojom::PageHandler> receiver) {
+  color_provider_handler_ = std::make_unique<ui::ColorChangeHandler>(
+      web_ui()->GetWebContents(), std::move(receiver));
+}
+
 WEB_UI_CONTROLLER_TYPE_IMPL(InternetDetailDialogUI)
 
 }  // namespace ash
diff --git a/chrome/browser/ui/webui/ash/internet_detail_dialog.h b/chrome/browser/ui/webui/ash/internet_detail_dialog.h
index 834dd63..47025ff 100644
--- a/chrome/browser/ui/webui/ash/internet_detail_dialog.h
+++ b/chrome/browser/ui/webui/ash/internet_detail_dialog.h
@@ -13,6 +13,13 @@
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "ui/gfx/native_widget_types.h"
 #include "ui/web_dialogs/web_dialog_ui.h"
+#include "ui/webui/resources/cr_components/color_change_listener/color_change_listener.mojom.h"
+
+namespace ui {
+
+class ColorChangeHandler;
+
+}  //  namespace ui
 
 namespace ash {
 
@@ -76,7 +83,14 @@
       mojo::PendingReceiver<chromeos::network_config::mojom::CrosNetworkConfig>
           receiver);
 
+  // Instantiates the implementor of the mojom::PageHandler mojo interface
+  // passing the pending receiver that will be internally bound.
+  void BindInterface(
+      mojo::PendingReceiver<color_change_listener::mojom::PageHandler>
+          receiver);
+
  private:
+  std::unique_ptr<ui::ColorChangeHandler> color_provider_handler_;
   WEB_UI_CONTROLLER_TYPE_DECL();
 };
 
diff --git a/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_ui.cc b/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_ui.cc
index d4e316c..ef9c35a1 100644
--- a/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_ui.cc
+++ b/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_ui.cc
@@ -40,6 +40,9 @@
   source->AddResourcePath(
       chrome::kChromeUIPrivacySandboxDialogNoticePath,
       IDR_PRIVACY_SANDBOX_PRIVACY_SANDBOX_NOTICE_DIALOG_HTML);
+  source->AddResourcePath(
+      chrome::kChromeUIPrivacySandboxDialogNoticeRestrictedPath,
+      IDR_PRIVACY_SANDBOX_PRIVACY_SANDBOX_NOTICE_RESTRICTED_DIALOG_HTML);
 
   static constexpr webui::LocalizedString kStrings[] = {
       {"privacySandboxTitle", IDS_SETTINGS_PRIVACY_SANDBOX_TITLE},
@@ -168,6 +171,9 @@
        IDS_PRIVACY_SANDBOX_M1_NOTICE_ROW_LEARN_MORE_DESCRIPTION_4},
       {"m1NoticeRowLearnMoreDescription5",
        IDS_PRIVACY_SANDBOX_M1_NOTICE_ROW_LEARN_MORE_DESCRIPTION_5},
+      // Strings for the restricted notice dialog (kM1NoticeRestricted).
+      {"m1NoticeRestrictedDescription1",
+       IDS_PRIVACY_SANDBOX_M1_NOTICE_RESTRICTED_DESCRIPTION_1},
       // Shared for all dialogs.
       {"m1DialogMoreButton", IDS_PRIVACY_SANDBOX_M1_DIALOG_MORE_BUTTON}};
 
@@ -195,7 +201,6 @@
              prompt_type == PrivacySandboxService::PromptType::kConsent);
   content::WebUIDataSource::Update(
       profile, chrome::kChromeUIPrivacySandboxDialogHost, std::move(update));
-
   auto handler = std::make_unique<PrivacySandboxDialogHandler>(
       std::move(close_callback), std::move(resize_callback),
       std::move(show_dialog_callback), std::move(open_settings_callback),
diff --git a/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks.mojom b/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks.mojom
index d25eefa..d670e9e9 100644
--- a/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks.mojom
+++ b/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks.mojom
@@ -20,9 +20,9 @@
 enum SortOrder {
   kNewest = 0,
   kOldest = 1,
-  kAlphabetical = 2,
-  kReverseAlphabetical = 3,
-  kLastOpened = 4,
+  kLastOpened = 2,
+  kAlphabetical = 3,
+  kReverseAlphabetical = 4,
 
   // Must be last. May add new values before this one.
   kCount = 5,
diff --git a/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc b/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc
index ccc0390..fba61b7 100644
--- a/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc
+++ b/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc
@@ -128,12 +128,6 @@
                           base::Unretained(this)));
 
   web_ui()->RegisterMessageCallback(
-      syncer::sync_ui_util::kRequestStopKeepData,
-      base::BindRepeating(
-          &SyncInternalsMessageHandler::HandleRequestStopKeepData,
-          base::Unretained(this)));
-
-  web_ui()->RegisterMessageCallback(
       syncer::sync_ui_util::kRequestStopClearData,
       base::BindRepeating(
           &SyncInternalsMessageHandler::HandleRequestStopClearData,
@@ -268,18 +262,6 @@
       syncer::SyncFirstSetupCompleteSource::BASIC_FLOW);
 }
 
-void SyncInternalsMessageHandler::HandleRequestStopKeepData(
-    const base::Value::List& args) {
-  DCHECK_EQ(0U, args.size());
-
-  SyncService* service = GetSyncService();
-  if (!service) {
-    return;
-  }
-
-  service->GetUserSettings()->ClearSyncRequested();
-}
-
 void SyncInternalsMessageHandler::HandleRequestStopClearData(
     const base::Value::List& args) {
   DCHECK_EQ(0U, args.size());
diff --git a/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.h b/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.h
index 70f43f2..5f44a4e 100644
--- a/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.h
+++ b/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.h
@@ -62,9 +62,6 @@
   // Handler for requestStart message.
   void HandleRequestStart(const base::Value::List& args);
 
-  // Handler for requestStopKeepData message.
-  void HandleRequestStopKeepData(const base::Value::List& args);
-
   // Handler for requestStopClearData message.
   void HandleRequestStopClearData(const base::Value::List& args);
 
diff --git a/chrome/browser/ui/webui/version/version_ui.cc b/chrome/browser/ui/webui/version/version_ui.cc
index 67545be..d0b6ded 100644
--- a/chrome/browser/ui/webui/version/version_ui.cc
+++ b/chrome/browser/ui/webui/version/version_ui.cc
@@ -55,6 +55,7 @@
 #endif
 
 #if BUILDFLAG(IS_WIN)
+#include "base/win/windows_version.h"
 #include "chrome/browser/ui/webui/version/version_handler_win.h"
 #include "chrome/browser/ui/webui/version/version_util_win.h"
 #endif
@@ -181,6 +182,23 @@
     case base::mac::CPUType::kArm:
       return IDS_VERSION_UI_64BIT_ARM;
   }
+#elif BUILDFLAG(IS_WIN)
+#if defined(ARCH_CPU_ARM64)
+  return IDS_VERSION_UI_64BIT_ARM;
+#else
+  bool emulated = base::win::OSInfo::IsRunningEmulatedOnArm64();
+#if defined(ARCH_CPU_X86)
+  if (emulated) {
+    return IDS_VERSION_UI_32BIT_TRANSLATED_INTEL;
+  }
+  return IDS_VERSION_UI_32BIT;
+#else   // defined(ARCH_CPU_X86)
+  if (emulated) {
+    return IDS_VERSION_UI_64BIT_TRANSLATED_INTEL;
+  }
+  return IDS_VERSION_UI_64BIT;
+#endif  // defined(ARCH_CPU_X86)
+#endif  // defined(ARCH_CPU_ARM64)
 #elif defined(ARCH_CPU_64_BITS)
   return IDS_VERSION_UI_64BIT;
 #elif defined(ARCH_CPU_32_BITS)
diff --git a/chrome/browser/web_applications/os_integration/web_app_shortcuts_menu_win.cc b/chrome/browser/web_applications/os_integration/web_app_shortcuts_menu_win.cc
index bb927a3..7fc40f6e 100644
--- a/chrome/browser/web_applications/os_integration/web_app_shortcuts_menu_win.cc
+++ b/chrome/browser/web_applications/os_integration/web_app_shortcuts_menu_win.cc
@@ -17,6 +17,7 @@
 #include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/no_destructor.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
@@ -40,6 +41,26 @@
 
 constexpr int kMaxJumpListItems = 10;
 
+constexpr const char* kShortcutsMenuRegistrationHistogram =
+    "WebApp.ShortcutsMenu.Win.Results";
+
+// This should be kept in sync with ShortcutsMenuWinRegistrationResult inside
+// tools/metrics/histograms/enums.xml
+enum class ShortcutsMenuRegistrationResult {
+  kSuccess = 0,
+  kFailedToCreateShortcutMenuIconsDirectory = 1,
+  kFailedToCreateIconFromImageFamily = 2,
+  kFailedToBeginJumplistUpdate = 3,
+  kFailedToAddLinkItemsToJumplist = 4,
+  kFailedToCommitJumplistUpdate = 5,
+  kMaxValue = kFailedToCommitJumplistUpdate
+};
+
+// Records the result of registering shortcuts menu on Win to UMA.
+void RecordShortcutsMenuResult(ShortcutsMenuRegistrationResult result) {
+  base::UmaHistogramEnumeration(kShortcutsMenuRegistrationHistogram, result);
+}
+
 // Testing hook for shell_integration_linux
 UpdateJumpListForTesting& GetUpdateJumpListForTesting() {
   static base::NoDestructor<UpdateJumpListForTesting> instance;
@@ -65,6 +86,8 @@
     const ShortcutsMenuIconBitmaps& shortcut_icons) {
   if (!base::CreateDirectory(
           GetShortcutsMenuIconsDirectory(shortcut_data_dir))) {
+    RecordShortcutsMenuResult(ShortcutsMenuRegistrationResult::
+                                  kFailedToCreateShortcutMenuIconsDirectory);
     return false;
   }
   int icon_index = -1;
@@ -81,6 +104,8 @@
       image_family.Add(gfx::Image::CreateFrom1xBitmap(item.second));
     }
     if (!IconUtil::CreateIconFileFromImageFamily(image_family, icon_file)) {
+      RecordShortcutsMenuResult(
+          ShortcutsMenuRegistrationResult::kFailedToCreateIconFromImageFamily);
       return false;
     }
   }
@@ -102,13 +127,24 @@
   }
 
   JumpListUpdater jumplist_updater(app_user_model_id);
-  if (!jumplist_updater.BeginUpdate())
+  if (!jumplist_updater.BeginUpdate()) {
+    RecordShortcutsMenuResult(
+        ShortcutsMenuRegistrationResult::kFailedToBeginJumplistUpdate);
     return false;
+  }
 
-  if (!jumplist_updater.AddTasks(link_items))
+  if (!jumplist_updater.AddTasks(link_items)) {
+    RecordShortcutsMenuResult(
+        ShortcutsMenuRegistrationResult::kFailedToAddLinkItemsToJumplist);
     return false;
+  }
 
-  return jumplist_updater.CommitUpdate();
+  bool success = jumplist_updater.CommitUpdate();
+  if (!success) {
+    RecordShortcutsMenuResult(
+        ShortcutsMenuRegistrationResult::kFailedToCommitJumplistUpdate);
+  }
+  return success;
 }
 
 }  // namespace
@@ -181,6 +217,9 @@
 
 void OnShortcutsMenuRegistrationComplete(RegisterShortcutsMenuCallback callback,
                                          bool registration_successful) {
+  if (registration_successful) {
+    RecordShortcutsMenuResult(ShortcutsMenuRegistrationResult::kSuccess);
+  }
   std::move(callback).Run(registration_successful ? Result::kOk
                                                   : Result::kError);
 }
diff --git a/chrome/browser/web_applications/scope_extension_info.cc b/chrome/browser/web_applications/scope_extension_info.cc
index 3139b76..7c4db4b 100644
--- a/chrome/browser/web_applications/scope_extension_info.cc
+++ b/chrome/browser/web_applications/scope_extension_info.cc
@@ -16,10 +16,10 @@
     : origin(origin), has_origin_wildcard(has_origin_wildcard) {}
 
 base::Value ScopeExtensionInfo::AsDebugValue() const {
-  base::Value root(base::Value::Type::DICT);
-  root.SetStringKey("origin", origin.GetDebugString());
-  root.SetBoolKey("has_origin_wildcard", has_origin_wildcard);
-  return root;
+  base::Value::Dict root = base::Value::Dict()
+                               .Set("origin", origin.GetDebugString())
+                               .Set("has_origin_wildcard", has_origin_wildcard);
+  return base::Value(std::move(root));
 }
 
 void ScopeExtensionInfo::Reset() {
diff --git a/chrome/browser/web_applications/web_app_chromeos_data.cc b/chrome/browser/web_applications/web_app_chromeos_data.cc
index 998de97a..9bb730d 100644
--- a/chrome/browser/web_applications/web_app_chromeos_data.cc
+++ b/chrome/browser/web_applications/web_app_chromeos_data.cc
@@ -11,14 +11,16 @@
 namespace web_app {
 
 base::Value WebAppChromeOsData::AsDebugValue() const {
-  base::Value root(base::Value::Type::DICT);
-  root.SetBoolKey("show_in_launcher", show_in_launcher);
-  root.SetBoolKey("show_in_search", show_in_search);
-  root.SetBoolKey("show_in_management", show_in_management);
-  root.SetBoolKey("is_disabled", is_disabled);
-  root.SetBoolKey("oem_installed", oem_installed);
-  root.SetBoolKey("handles_file_open_intents", handles_file_open_intents);
-  return root;
+  base::Value::Dict root =
+      base::Value::Dict()
+          .Set("show_in_launcher", show_in_launcher)
+          .Set("show_in_search", show_in_search)
+          .Set("show_in_management", show_in_management)
+          .Set("is_disabled", is_disabled)
+          .Set("oem_installed", oem_installed)
+          .Set("handles_file_open_intents", handles_file_open_intents);
+
+  return base::Value(std::move(root));
 }
 
 bool operator==(const WebAppChromeOsData& chromeos_data1,
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index d6a1e10..9c3767e 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1681394130-10b03420552d3a7e771d382d6e276bfe2e51e1f6.profdata
+chrome-mac-arm-main-1681408779-19562355795693dc9271fba711025a47c2a3373e.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index abb63da2..e706f7a 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1681376373-fbe671e0f7d99283c72bb1c3dc3f3820de4f8a59.profdata
+chrome-win32-main-1681397997-e43e6f3cbcaa1aa4b0d5bae4dfd28e661595bd29.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 9e26dec7..1b04ce3 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1681386955-d6d720bb8e09c04489f197f8c5d4f584c48f89cf.profdata
+chrome-win64-main-1681397997-1a8c5ec9d0f5a3f3ea4e108a5fc9e8ee887cae84.profdata
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc
index e149c52..43071ff 100644
--- a/chrome/common/webui_url_constants.cc
+++ b/chrome/common/webui_url_constants.cc
@@ -166,6 +166,7 @@
     "chrome://privacy-sandbox-dialog";
 const char kChromeUIPrivacySandboxDialogCombinedPath[] = "combined";
 const char kChromeUIPrivacySandboxDialogNoticePath[] = "notice";
+const char kChromeUIPrivacySandboxDialogNoticeRestrictedPath[] = "restricted";
 const char kChromeUIPrivacySandboxFledgeURL[] =
     "chrome://settings/adPrivacy/sites";
 const char kChromeUIPrivacySandboxTopicsURL[] =
diff --git a/chrome/common/webui_url_constants.h b/chrome/common/webui_url_constants.h
index 3d09c92..8d3bb6e 100644
--- a/chrome/common/webui_url_constants.h
+++ b/chrome/common/webui_url_constants.h
@@ -168,6 +168,7 @@
 extern const char kChromeUIPrivacySandboxDialogURL[];
 extern const char kChromeUIPrivacySandboxDialogCombinedPath[];
 extern const char kChromeUIPrivacySandboxDialogNoticePath[];
+extern const char kChromeUIPrivacySandboxDialogNoticeRestrictedPath[];
 extern const char kChromeUIPrivacySandboxFledgeURL[];
 extern const char kChromeUIPrivacySandboxTopicsURL[];
 extern const char kChromeUIProfileInternalsHost[];
diff --git a/chrome/renderer/chrome_render_thread_observer.cc b/chrome/renderer/chrome_render_thread_observer.cc
index 9ac378b..d3c5669 100644
--- a/chrome/renderer/chrome_render_thread_observer.cc
+++ b/chrome/renderer/chrome_render_thread_observer.cc
@@ -32,6 +32,7 @@
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/media/media_resource_provider.h"
 #include "chrome/common/net/net_resource_provider.h"
+#include "chrome/common/renderer_configuration.mojom.h"
 #include "chrome/common/url_constants.h"
 #include "components/visitedlink/renderer/visitedlink_reader.h"
 #include "content/public/child/child_thread.h"
@@ -127,11 +128,6 @@
 }
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-chrome::mojom::DynamicParams* GetDynamicConfigParams() {
-  static base::NoDestructor<chrome::mojom::DynamicParams> dynamic_params;
-  return dynamic_params.get();
-}
-
 ChromeRenderThreadObserver::ChromeRenderThreadObserver()
     : visited_link_reader_(new visitedlink::VisitedLinkReader) {
   // Configure modules that need access to resources.
@@ -141,10 +137,15 @@
 
 ChromeRenderThreadObserver::~ChromeRenderThreadObserver() {}
 
-// static
-const chrome::mojom::DynamicParams&
-ChromeRenderThreadObserver::GetDynamicParams() {
-  return *GetDynamicConfigParams();
+chrome::mojom::DynamicParams ChromeRenderThreadObserver::GetDynamicParams()
+    const {
+  {
+    base::AutoLock lock(dynamic_params_lock_);
+    if (dynamic_params_) {
+      return *dynamic_params_;
+    }
+  }
+  return chrome::mojom::DynamicParams();
 }
 
 void ChromeRenderThreadObserver::RegisterMojoInterfaces(
@@ -180,7 +181,8 @@
 
 void ChromeRenderThreadObserver::SetConfiguration(
     chrome::mojom::DynamicParamsPtr params) {
-  *GetDynamicConfigParams() = std::move(*params);
+  base::AutoLock lock(dynamic_params_lock_);
+  dynamic_params_ = std::move(params);
 }
 
 void ChromeRenderThreadObserver::OnRendererConfigurationAssociatedRequest(
diff --git a/chrome/renderer/chrome_render_thread_observer.h b/chrome/renderer/chrome_render_thread_observer.h
index ad37007..4a4ba4bf 100644
--- a/chrome/renderer/chrome_render_thread_observer.h
+++ b/chrome/renderer/chrome_render_thread_observer.h
@@ -7,6 +7,8 @@
 
 #include <memory>
 
+#include "base/synchronization/lock.h"
+#include "base/thread_annotations.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/common/renderer_configuration.mojom.h"
 #include "components/content_settings/common/content_settings_manager.mojom.h"
@@ -83,9 +85,9 @@
 
   static bool is_incognito_process() { return is_incognito_process_; }
 
-  // Return the dynamic parameters - those that may change while the
+  // Return a copy of the dynamic parameters - those that may change while the
   // render process is running.
-  static const chrome::mojom::DynamicParams& GetDynamicParams();
+  chrome::mojom::DynamicParams GetDynamicParams() const;
 
   visitedlink::VisitedLinkReader* visited_link_reader() {
     return visited_link_reader_.get();
@@ -131,6 +133,10 @@
   mojo::AssociatedReceiverSet<chrome::mojom::RendererConfiguration>
       renderer_configuration_receivers_;
 
+  chrome::mojom::DynamicParamsPtr dynamic_params_
+      GUARDED_BY(dynamic_params_lock_);
+  mutable base::Lock dynamic_params_lock_;
+
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   // Only set if the Chrome OS merge session was running when the renderer
   // was started.
diff --git a/chrome/renderer/url_loader_throttle_provider_impl.cc b/chrome/renderer/url_loader_throttle_provider_impl.cc
index 3797bc0..72bd8e1 100644
--- a/chrome/renderer/url_loader_throttle_provider_impl.cc
+++ b/chrome/renderer/url_loader_throttle_provider_impl.cc
@@ -190,7 +190,8 @@
 #if BUILDFLAG(IS_ANDROID)
       client_data_header,
 #endif
-      ChromeRenderThreadObserver::GetDynamicParams()));
+      chrome_content_renderer_client_->GetChromeObserver()
+          ->GetDynamicParams()));
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   throttles.emplace_back(std::make_unique<AshMergeSessionLoaderThrottle>(
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 9768703..674046ab 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -605,9 +605,9 @@
 
   if (is_chromeos_ash) {
     sources += [
-      "../browser/ash/login/app_mode/test/ash_accelerator_helpers.cc",
       "../browser/apps/app_service/metrics/app_platform_metrics_service_test_base.cc",
       "../browser/apps/app_service/metrics/app_platform_metrics_service_test_base.h",
+      "../browser/ash/login/app_mode/test/ash_accelerator_helpers.cc",
       "../browser/ash/login/lock/screen_locker_tester.cc",
       "../browser/ash/login/lock/screen_locker_tester.h",
       "../browser/ash/login/saml/lockscreen_reauth_dialog_test_helper.cc",
@@ -9128,10 +9128,10 @@
       sources += [
         "../browser/supervised_user/chromeos/mock_large_icon_service.cc",
         "../browser/supervised_user/chromeos/mock_large_icon_service.h",
+        "../browser/supervised_user/chromeos/web_content_handler_impl_unittest.cc",
       ]
     }
     if (is_chromeos_ash) {
-      sources += [ "../browser/supervised_user/chromeos/web_content_handler_impl_unittest.cc" ]
       deps += [ "//chrome/browser/ash/crosapi" ]
     }
     if (is_android) {
diff --git a/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js b/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js
index f230f6f..542d933 100644
--- a/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js
+++ b/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js
@@ -20,32 +20,58 @@
 var kDefaultPuk = '12345678';
 
 var privateHelpers = {
-  // Watches for the states |expectedStates| in reverse order. If all states
-  // were observed in the right order, succeeds and calls |done|. If any
+  // networkToExpectedStatesMap is a Map string (network GUID) -> array of
+  // strings (expected states).
+  // For each network specified there, watches for onNetworksChanged events with
+  // the specified states, in reverse order.
+  // If all states were observed (in the right order), succeeds and calls
+  // |done|. If any
   // unexpected state is observed, fails.
-  watchForStateChanges: function(network, expectedStates, done) {
-    var self = this;
-    var collectProperties = function(properties) {
-      var finishTest = function() {
+  watchForStateChanges: function(networkToExpectedStatesMap, done) {
+    const networkToLastSeenState = new Map();
+    const self = this;
+    const collectProperties = function(network, properties) {
+      const finishTest = function() {
         chrome.networkingPrivate.onNetworksChanged.removeListener(
             self.onNetworkChange);
         done();
       };
+      const currentState = properties.ConnectionState;
+
+      // Ignore if the state has not changed.
+      const lastSeenState = networkToLastSeenState.get(network);
+      if (lastSeenState && lastSeenState === currentState) {
+        return;
+      }
+      networkToLastSeenState.set(network, currentState);
+
+      const expectedStates = networkToExpectedStatesMap.get(network);
+      if (!expectedStates) {
+        chrome.test.fail(
+            'Unexpected state change for network ' + network + ' (' + +')');
+      }
       if (expectedStates.length > 0) {
-        var expectedState = expectedStates.pop();
-        assertEq(expectedState, properties.ConnectionState);
-        if (expectedStates.length == 0)
-          finishTest();
+        const expectedState = expectedStates.pop();
+        assertEq(expectedState, currentState);
+        if (expectedStates.length == 0) {
+          networkToExpectedStatesMap.delete(network);
+        }
+      }
+      if (networkToExpectedStatesMap.size == 0) {
+        finishTest();
       }
     };
     this.onNetworkChange = function(changes) {
-      assertEq([network], changes);
-      chrome.networkingPrivate.getProperties(
-          network,
-          callbackPass(collectProperties));
+      for (let network of changes) {
+        assertTrue(networkToExpectedStatesMap.has(network));
+        chrome.networkingPrivate.getProperties(
+            network, callbackPass(function(properties) {
+              collectProperties(network, properties);
+            }));
+      }
     };
     chrome.networkingPrivate.onNetworksChanged.addListener(
-        this.onNetworkChange);
+        self.onNetworkChange);
   },
   networkListChangedListener: function(expected, done) {
     function listener(list) {
@@ -831,17 +857,19 @@
   function onNetworksChangedEventConnect() {
     var network = 'stub_wifi2_guid';
     var done = chrome.test.callbackAdded();
-    var expectedStates = [ConnectionStateType.CONNECTED];
-    var listener =
-        new privateHelpers.watchForStateChanges(network, expectedStates, done);
+    var listener = new privateHelpers.watchForStateChanges(
+        new Map([
+          ['stub_wifi1_guid', [ConnectionStateType.NOT_CONNECTED]],
+          [network, [ConnectionStateType.CONNECTED]]
+        ]),
+        done);
     chrome.networkingPrivate.startConnect(network, networkCallbackPass());
   },
   function onNetworksChangedEventDisconnect() {
     var network = 'stub_wifi1_guid';
     var done = chrome.test.callbackAdded();
-    var expectedStates = [ConnectionStateType.NOT_CONNECTED];
-    var listener =
-        new privateHelpers.watchForStateChanges(network, expectedStates, done);
+    var listener = new privateHelpers.watchForStateChanges(
+        new Map([[network, [ConnectionStateType.NOT_CONNECTED]]]), done);
     chrome.networkingPrivate.startDisconnect(network, networkCallbackPass());
   },
   function onNetworkListChangedEvent() {
diff --git a/chrome/test/data/webui/chromeos/internet_detail_dialog_test.js b/chrome/test/data/webui/chromeos/internet_detail_dialog_test.js
index 329af08..fe645945 100644
--- a/chrome/test/data/webui/chromeos/internet_detail_dialog_test.js
+++ b/chrome/test/data/webui/chromeos/internet_detail_dialog_test.js
@@ -405,4 +405,25 @@
         assertTrue(!!internetDetailDialog.shadowRoot.querySelector('apn-list')
                          .shadowRoot.querySelector('apn-detail-dialog'));
       });
+
+  [false, true].forEach(isJellyEnabled => {
+    test('Dynamic theme CSS is added when isJellyEnabled is set', async () => {
+      loadTimeData.overrideValues({
+        isJellyEnabled: isJellyEnabled,
+      });
+      await setupCellularNetwork(
+          /*isPrimary=*/ true, /*isInhibited=*/ false);
+      await init();
+
+      const linkEl =
+          document.querySelector('link[href*=\'chrome://theme/colors.css\']');
+      if (isJellyEnabled) {
+        assertTrue(!!linkEl);
+        assertTrue(document.body.classList.contains('jelly-enabled'));
+      } else {
+        assertEquals(null, linkEl);
+        assertFalse(document.body.classList.contains('jelly-enabled'));
+      }
+    });
+  });
 });
diff --git a/chrome/test/data/webui/password_manager/move_passwords_dialog_test.ts b/chrome/test/data/webui/password_manager/move_passwords_dialog_test.ts
index 8b1aa6b..dfa0b52 100644
--- a/chrome/test/data/webui/password_manager/move_passwords_dialog_test.ts
+++ b/chrome/test/data/webui/password_manager/move_passwords_dialog_test.ts
@@ -5,7 +5,7 @@
 import 'chrome://password-manager/password_manager.js';
 
 import {PasswordManagerImpl, SyncBrowserProxyImpl} from 'chrome://password-manager/password_manager.js';
-import {assertEquals} from 'chrome://webui-test/chai_assert.js';
+import {assertArrayEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {flushTasks} from 'chrome://webui-test/polymer_test_util.js';
 
 import {TestPasswordManagerProxy} from './test_password_manager_proxy.js';
@@ -32,6 +32,7 @@
       createAffiliatedDomain('test.com'),
       createAffiliatedDomain('m.test.com'),
     ];
+    passwordManager.setRequestCredentialsDetailsResponse([password]);
 
     syncProxy.accountInfo = {
       email: 'test@gmail.com',
@@ -43,8 +44,136 @@
     document.body.appendChild(dialog);
     await flushTasks();
 
+    assertTrue(dialog.$.dialog.open);
     assertEquals(
         syncProxy.accountInfo.email, dialog.$.accountEmail.textContent!.trim());
     assertEquals(syncProxy.accountInfo.avatarImage, dialog.$.avatar.src);
+
+    const passwordItems =
+        dialog.shadowRoot!.querySelectorAll('password-preview-item');
+    assertEquals(1, passwordItems.length);
+
+    const passwordItem = passwordItems[0];
+    assertTrue(!!passwordItem);
+    // Checked by default.
+    assertTrue(passwordItem.$.checkbox.checked);
+    assertTrue(passwordItem.checked);
+    assertEquals(password.id, passwordItem.passwordId);
+    assertEquals(
+        password.affiliatedDomains[0]!.name,
+        passwordItem.$.website.textContent!.trim());
+    assertEquals(
+        password.username, passwordItem.$.username.textContent!.trim());
+    // Password hidden by default.
+    assertEquals('password', passwordItem.$.password.type);
+
+    passwordItem.$.showPasswordButton.click();
+    assertEquals('text', passwordItem.$.password.type);
+    assertEquals(password.password, passwordItem.$.password.value);
+  });
+
+  test('Move passwords', async function() {
+    const passwords = [
+      createPasswordEntry({id: 0, username: 'user1', password: 'sTr0nGp@@s'}),
+      createPasswordEntry({id: 1, username: 'user2', password: 'sTr0nGp@@s'}),
+      createPasswordEntry({id: 2, username: 'user1', password: 'sTr0nGp@@s'}),
+    ];
+    passwords.forEach(
+        item => item.affiliatedDomains = [createAffiliatedDomain('test.com')]);
+    passwordManager.setRequestCredentialsDetailsResponse(passwords);
+    passwordManager.data.isOptedInAccountStorage = true;
+
+    syncProxy.accountInfo = {
+      email: 'test@gmail.com',
+      avatarImage: 'chrome://image-url/',
+    };
+    syncProxy.syncInfo = {isEligibleForAccountStorage: true};
+
+    const dialog = document.createElement('move-passwords-dialog');
+    dialog.passwords = passwords;
+    document.body.appendChild(dialog);
+    await flushTasks();
+
+    dialog.$.move.click();
+
+    const ids = await passwordManager.whenCalled('movePasswordsToAccount');
+    assertArrayEquals([0, 1, 2], ids);
+  });
+
+  test('Move only selected passwords', async function() {
+    const passwords = [
+      createPasswordEntry({id: 0, username: 'user1', password: 'sTr0nGp@@s'}),
+      createPasswordEntry({id: 1, username: 'user2', password: 'sTr0nGp@@s'}),
+      createPasswordEntry({id: 2, username: 'user1', password: 'sTr0nGp@@s'}),
+    ];
+    passwords.forEach(
+        item => item.affiliatedDomains = [createAffiliatedDomain('test.com')]);
+    passwordManager.setRequestCredentialsDetailsResponse(passwords);
+    passwordManager.data.isOptedInAccountStorage = true;
+
+    syncProxy.accountInfo = {
+      email: 'test@gmail.com',
+      avatarImage: 'chrome://image-url/',
+    };
+    syncProxy.syncInfo = {isEligibleForAccountStorage: true};
+
+    const dialog = document.createElement('move-passwords-dialog');
+    dialog.passwords = passwords;
+    document.body.appendChild(dialog);
+    await flushTasks();
+
+    const passwordItems =
+        dialog.shadowRoot!.querySelectorAll('password-preview-item');
+    assertEquals(3, passwordItems.length);
+
+    // Deselect 2nd item.
+    passwordItems[1]!.$.checkbox.click();
+
+    dialog.$.move.click();
+
+    const ids = await passwordManager.whenCalled('movePasswordsToAccount');
+    assertArrayEquals([0, 2], ids);
+  });
+
+  test('Move dialog not shown when auth fails', async function() {
+    const password = createPasswordEntry({id: 0, username: 'user1'});
+    password.affiliatedDomains = [createAffiliatedDomain('test.com')];
+
+    const dialog = document.createElement('move-passwords-dialog');
+    dialog.passwords = [password];
+    document.body.appendChild(dialog);
+    await flushTasks();
+
+    assertFalse(dialog.$.dialog.open);
+  });
+
+  test('Move button disabled when nothing to move', async function() {
+    const passwords = [
+      createPasswordEntry({id: 0, username: 'user1', password: 'sTr0nGp@@s'}),
+      createPasswordEntry({id: 1, username: 'user2', password: 'sTr0nGp@@s'}),
+      createPasswordEntry({id: 2, username: 'user1', password: 'sTr0nGp@@s'}),
+    ];
+    passwords.forEach(
+        item => item.affiliatedDomains = [createAffiliatedDomain('test.com')]);
+    passwordManager.setRequestCredentialsDetailsResponse(passwords);
+    passwordManager.data.isOptedInAccountStorage = true;
+
+    syncProxy.accountInfo = {
+      email: 'test@gmail.com',
+      avatarImage: 'chrome://image-url/',
+    };
+    syncProxy.syncInfo = {isEligibleForAccountStorage: true};
+
+    const dialog = document.createElement('move-passwords-dialog');
+    dialog.passwords = passwords;
+    document.body.appendChild(dialog);
+    await flushTasks();
+
+    const passwordItems =
+        dialog.shadowRoot!.querySelectorAll('password-preview-item');
+    assertEquals(3, passwordItems.length);
+    passwordItems.forEach(item => item.$.checkbox.click());
+
+    assertTrue(dialog.$.move.disabled);
   });
 });
diff --git a/chrome/test/data/webui/password_manager/passwords_section_test.ts b/chrome/test/data/webui/password_manager/passwords_section_test.ts
index 56855b1..0be928d8 100644
--- a/chrome/test/data/webui/password_manager/passwords_section_test.ts
+++ b/chrome/test/data/webui/password_manager/passwords_section_test.ts
@@ -446,9 +446,15 @@
     passwordManager.data.isOptedInAccountStorage = true;
     passwordManager.data.groups = [createCredentialGroup({
       name: 'test.com',
-      credentials: [createPasswordEntry(
-          {username: 'user', id: 0, inProfileStore: true})],
+      credentials: [createPasswordEntry({
+        username: 'user',
+        id: 0,
+        inProfileStore: true,
+        affiliatedDomains: [createAffiliatedDomain('test.com')],
+      })],
     })];
+    passwordManager.setRequestCredentialsDetailsResponse(
+        passwordManager.data.groups[0]!.entries);
     syncProxy.syncInfo = {
       isEligibleForAccountStorage: true,
     };
diff --git a/chrome/test/data/webui/password_manager/test_password_manager_proxy.ts b/chrome/test/data/webui/password_manager/test_password_manager_proxy.ts
index 2b692e6..a9cd260 100644
--- a/chrome/test/data/webui/password_manager/test_password_manager_proxy.ts
+++ b/chrome/test/data/webui/password_manager/test_password_manager_proxy.ts
@@ -56,6 +56,7 @@
       'getPasswordCheckStatus',
       'getSavedPasswordList',
       'getUrlCollection',
+      'movePasswordsToAccount',
       'muteInsecureCredential',
       'optInForAccountStorage',
       'recordPasswordCheckInteraction',
@@ -316,4 +317,8 @@
     this.methodCalled('isAccountStoreDefault');
     return Promise.resolve(this.data.isAccountStorageDefault);
   }
+
+  movePasswordsToAccount(ids: number[]) {
+    this.methodCalled('movePasswordsToAccount', ids);
+  }
 }
diff --git a/chrome/test/data/webui/password_manager/test_util.ts b/chrome/test/data/webui/password_manager/test_util.ts
index 2ac6bb4..cd8f7db7 100644
--- a/chrome/test/data/webui/password_manager/test_util.ts
+++ b/chrome/test/data/webui/password_manager/test_util.ts
@@ -31,6 +31,7 @@
   inProfileStore?: boolean;
   isAndroidCredential?: boolean;
   note?: string;
+  affiliatedDomains?: chrome.passwordsPrivate.DomainInfo[];
 }
 
 /**
@@ -73,6 +74,7 @@
     isAndroidCredential: params.isAndroidCredential || false,
     note: note,
     password: params.password || '',
+    affiliatedDomains: params.affiliatedDomains,
   };
 }
 
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 1c9847d8..2658f562 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
@@ -4,6 +4,7 @@
 
 import 'chrome://privacy-sandbox-dialog/privacy_sandbox_dialog_app.js';
 import 'chrome://privacy-sandbox-dialog/privacy_sandbox_notice_dialog_app.js';
+import 'chrome://privacy-sandbox-dialog/privacy_sandbox_notice_restricted_dialog_app.js';
 import 'chrome://privacy-sandbox-dialog/privacy_sandbox_combined_dialog_app.js';
 
 import {PrivacySandboxCombinedDialogAppElement, PrivacySandboxCombinedDialogStep} from 'chrome://privacy-sandbox-dialog/privacy_sandbox_combined_dialog_app.js';
@@ -13,6 +14,7 @@
 import {PrivacySandboxDialogMixin} from 'chrome://privacy-sandbox-dialog/privacy_sandbox_dialog_mixin.js';
 import {PrivacySandboxDialogNoticeStepElement} from 'chrome://privacy-sandbox-dialog/privacy_sandbox_dialog_notice_step';
 import {PrivacySandboxNoticeDialogAppElement} from 'chrome://privacy-sandbox-dialog/privacy_sandbox_notice_dialog_app.js';
+import {PrivacySandboxNoticeRestrictedDialogAppElement} from 'chrome://privacy-sandbox-dialog/privacy_sandbox_notice_restricted_dialog_app.js';
 import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
 import {pressAndReleaseKeyOn} from 'chrome://resources/polymer/v3_0/iron-test-helpers/mock-interactions.js';
@@ -735,6 +737,29 @@
   });
 });
 
+suite('PrivacySandboxDialogNoticeRestricted', function() {
+  let page: PrivacySandboxNoticeRestrictedDialogAppElement;
+  let browserProxy: TestPrivacySandboxDialogBrowserProxy;
+
+  setup(async function() {
+    browserProxy = new TestPrivacySandboxDialogBrowserProxy();
+    PrivacySandboxDialogBrowserProxy.setInstance(browserProxy);
+
+    document.body.innerHTML = window.trustedTypes!.emptyHTML;
+    page =
+        document.createElement('privacy-sandbox-notice-restricted-dialog-app');
+    document.body.appendChild(page);
+    await browserProxy.whenCalled('resizeDialog');
+    await browserProxy.whenCalled('showDialog');
+  });
+
+  test('validDialog', async function() {
+    // Asserting very basic functionality for now.
+    // TODO(b/277180677): add more tests as functionality is implemented.
+    assertTrue(!!page.shadowRoot!.querySelector('div'));
+  });
+});
+
 suite('PrivacySandboxDialogMixin', function() {
   const TestElementBase = PrivacySandboxDialogMixin(PolymerElement);
 
diff --git a/chrome/test/data/webui/settings/BUILD.gn b/chrome/test/data/webui/settings/BUILD.gn
index bc0a325..e29a69f 100644
--- a/chrome/test/data/webui/settings/BUILD.gn
+++ b/chrome/test/data/webui/settings/BUILD.gn
@@ -201,6 +201,10 @@
     files += [ "incompatible_applications_page_test.ts" ]
   }
 
+  if (is_chrome_branded) {
+    files += [ "get_most_chrome_page_test.ts" ]
+  }
+
   ts_path_mappings = [
     # Settings tests should only be importing from one of the URLs below, so
     # that tests work both in optimize_webui=true/false modes.
diff --git a/chrome/test/data/webui/settings/advanced_page_test.ts b/chrome/test/data/webui/settings/advanced_page_test.ts
index 1ff212d..dd31556 100644
--- a/chrome/test/data/webui/settings/advanced_page_test.ts
+++ b/chrome/test/data/webui/settings/advanced_page_test.ts
@@ -5,6 +5,9 @@
 /** @fileoverview Suite of tests for the Settings advanced page. */
 
 // clang-format off
+// <if expr="_google_chrome">
+import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
+// </if>
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {CrSettingsPrefs, SettingsBasicPageElement, SettingsSectionElement} from 'chrome://settings/settings.js';
 import {assertEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
@@ -17,6 +20,9 @@
   let basicPage: SettingsBasicPageElement;
 
   suiteSetup(function() {
+    // <if expr="_google_chrome">
+    loadTimeData.overrideValues({showGetTheMostOutOfChromeSection: true});
+    // </if>
     document.body.innerHTML = window.trustedTypes!.emptyHTML;
     const settingsUi = document.createElement('settings-ui');
     document.body.appendChild(settingsUi);
@@ -82,6 +88,9 @@
 
   test('advanced pages', function() {
     const sections = ['a11y', 'languages', 'downloads', 'reset'];
+    // <if expr="_google_chrome">
+    sections.push('getMostChrome');
+    // </if>
     for (let i = 0; i < sections.length; i++) {
       const section = getSection(basicPage, sections[i]!);
       assertTrue(!!section);
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js
index b037f55..ff8713f 100644
--- a/chrome/test/data/webui/settings/cr_settings_browsertest.js
+++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -1005,6 +1005,10 @@
 registerTest('MetricsReporting', 'metrics_reporting_tests.js');
 GEN('#endif');
 
+GEN('#if BUILDFLAG(GOOGLE_CHROME_BRANDING)');
+registerTest('GetMostChromePage', 'get_most_chrome_page_test.js');
+GEN('#endif');
+
 function registerTest(testName, module, caseName) {
   const className = `CrSettings${testName}Test`;
   this[className] = class extends CrSettingsBrowserTest {
diff --git a/chrome/test/data/webui/settings/get_most_chrome_page_test.ts b/chrome/test/data/webui/settings/get_most_chrome_page_test.ts
new file mode 100644
index 0000000..68cafbb
--- /dev/null
+++ b/chrome/test/data/webui/settings/get_most_chrome_page_test.ts
@@ -0,0 +1,26 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'chrome://settings/lazy_load.js';
+
+import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {SettingsGetMostChromePageElement} from 'chrome://settings/lazy_load.js';
+import {assertTrue} from 'chrome://webui-test/chai_assert.js';
+
+/** @fileoverview Suite of tests for get_most_chrome_page. */
+suite('GetMostChromePage', function() {
+  let testElement: SettingsGetMostChromePageElement;
+
+  setup(function() {
+    document.body.innerHTML = window.trustedTypes!.emptyHTML;
+    testElement = document.createElement('settings-get-most-chrome-page');
+    document.body.appendChild(testElement);
+    flush();
+  });
+
+  test('Basic', function() {
+    assertTrue(!!testElement);
+    // TODO(crbug.com/143278): Expand this test as the element gets implemented.
+  });
+});
diff --git a/chromeos/ash/components/dbus/shill/fake_shill_service_client.cc b/chromeos/ash/components/dbus/shill/fake_shill_service_client.cc
index d84878e..38616e7 100644
--- a/chromeos/ash/components/dbus/shill/fake_shill_service_client.cc
+++ b/chromeos/ash/components/dbus/shill/fake_shill_service_client.cc
@@ -861,12 +861,40 @@
             base::IgnoreResult(&FakeShillServiceClient::SetServiceProperty),
             weak_ptr_factory_.GetWeakPtr(), service_path, shill::kErrorProperty,
             base::Value(shill::kErrorBadPassphrase)));
-  } else {
-    // Set Online.
-    VLOG(1) << "Setting state to Online " << service_path;
-    SetServiceProperty(service_path, shill::kStateProperty,
-                       base::Value(shill::kStateOnline));
+    return;
   }
+
+  // Set other services of the same type that were previously not "idle" to
+  // "idle".
+  const std::string* service_type =
+      service_properties->FindString(shill::kTypeProperty);
+  for (const auto service_pair : stub_services_) {
+    const auto& other_service_path = service_pair.first;
+    if (other_service_path == service_path) {
+      continue;
+    }
+
+    const base::Value::Dict& other_service_properties =
+        service_pair.second.GetDict();
+    const std::string* other_service_type =
+        other_service_properties.FindString(shill::kTypeProperty);
+    if (!service_type || !other_service_type ||
+        *other_service_type != *service_type) {
+      continue;
+    }
+    const std::string* other_service_state =
+        other_service_properties.FindString(shill::kStateProperty);
+    if (!other_service_state || *other_service_type == shill::kStateIdle) {
+      continue;
+    }
+    SetServiceProperty(other_service_path, shill::kStateProperty,
+                       base::Value(shill::kStateIdle));
+  }
+
+  // Set the connected service to "online".
+  VLOG(1) << "Setting state to Online " << service_path;
+  SetServiceProperty(service_path, shill::kStateProperty,
+                     base::Value(shill::kStateOnline));
 }
 
 void FakeShillServiceClient::SetDefaultFakeTrafficCounters() {
diff --git a/chromeos/ash/components/nearby/presence/credentials/BUILD.gn b/chromeos/ash/components/nearby/presence/credentials/BUILD.gn
index 7901448..03974ba 100644
--- a/chromeos/ash/components/nearby/presence/credentials/BUILD.gn
+++ b/chromeos/ash/components/nearby/presence/credentials/BUILD.gn
@@ -12,14 +12,20 @@
     "local_device_data_provider.h",
     "local_device_data_provider_impl.cc",
     "local_device_data_provider_impl.h",
+    "nearby_presence_credential_manager.h",
+    "nearby_presence_credential_manager_impl.cc",
+    "nearby_presence_credential_manager_impl.h",
     "nearby_presence_server_client.h",
     "nearby_presence_server_client_impl.cc",
     "nearby_presence_server_client_impl.h",
+    "prefs.cc",
+    "prefs.h",
     "proto_conversions.cc",
     "proto_conversions.h",
   ]
 
   deps = [
+    "//base",
     "//chromeos/ash/components/nearby/common/client",
     "//chromeos/ash/components/nearby/presence/proto",
     "//components/prefs",
@@ -42,6 +48,7 @@
 
   sources = [
     "local_device_data_provider_impl_unittest.cc",
+    "nearby_presence_credential_manager_impl_unittest.cc",
     "nearby_presence_server_client_impl_unittest.cc",
     "proto_conversions_unittest.cc",
   ]
diff --git a/chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl.cc b/chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl.cc
index decc3b73..912f40c 100644
--- a/chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl.cc
+++ b/chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl.cc
@@ -4,13 +4,27 @@
 
 #include "chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl.h"
 
+#include "base/rand_util.h"
+#include "chromeos/ash/components/nearby/presence/credentials/prefs.h"
 #include "chromeos/ash/components/nearby/presence/credentials/proto_conversions.h"
 #include "components/prefs/pref_service.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
+#include "google_apis/gaia/gaia_auth_util.h"
 
 namespace {
 
-constexpr char kPlaceHolderString[] = "0123456789";
+// Using the alphanumeric characters below, this provides 36^10 unique device
+// IDs. Note that the uniqueness requirement is not global; the IDs are only
+// used to differentiate between devices associated with a single GAIA account.
+const size_t kDeviceIdLength = 10;
+
+// Possible characters used in a randomly generated device ID.
+constexpr std::array<char, 36> kAlphaNumericChars = {
+    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+    'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+    'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
+
+const std::string& kPlaceHolderString = "0123456789";
 
 }  // namespace
 
@@ -18,9 +32,10 @@
 
 LocalDeviceDataProviderImpl::LocalDeviceDataProviderImpl(
     PrefService* pref_service,
-    signin::IdentityManager* identity_manager) {
-  CHECK(identity_manager);
-  CHECK(pref_service);
+    signin::IdentityManager* identity_manager)
+    : pref_service_(pref_service), identity_manager_(identity_manager) {
+  CHECK(identity_manager_);
+  CHECK(pref_service_);
 }
 
 LocalDeviceDataProviderImpl::~LocalDeviceDataProviderImpl() = default;
@@ -38,9 +53,22 @@
 }
 
 std::string LocalDeviceDataProviderImpl::GetDeviceId() {
-  // TODO (b/276307539): Implement `GetDeviceId`, this
-  // default implementation is to get the skeleton class to compile.
-  return kPlaceHolderString;
+  std::string id =
+      pref_service_->GetString(prefs::kNearbyPresenceDeviceIdPrefName);
+
+  // If the local device ID has already been generated, then return it. If this
+  // this is the first time `GetDeviceID` has been called, then generate the
+  // local device ID, persist it, and return it to callers.
+  if (!id.empty()) {
+    return id;
+  }
+
+  for (size_t i = 0; i < kDeviceIdLength; ++i) {
+    id += kAlphaNumericChars[base::RandGenerator(kAlphaNumericChars.size())];
+  }
+
+  pref_service_->SetString(prefs::kNearbyPresenceDeviceIdPrefName, id);
+  return id;
 }
 
 ::nearby::internal::Metadata LocalDeviceDataProviderImpl::GetDeviceMetadata() {
@@ -56,9 +84,10 @@
 }
 
 std::string LocalDeviceDataProviderImpl::GetAccountName() {
-  // TODO (b/276307539): Implement `GetAccountName`, this
-  // default implementation is to get the skeleton class to compile.
-  return kPlaceHolderString;
+  const std::string& email =
+      identity_manager_->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin)
+          .email;
+  return gaia::CanonicalizeEmail(email);
 }
 
 void LocalDeviceDataProviderImpl::SaveUserRegistrationInfo(
diff --git a/chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl.h b/chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl.h
index 4f63be9..623d40c43 100644
--- a/chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl.h
+++ b/chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl.h
@@ -5,6 +5,7 @@
 #ifndef CHROMEOS_ASH_COMPONENTS_NEARBY_PRESENCE_CREDENTIALS_LOCAL_DEVICE_DATA_PROVIDER_IMPL_H_
 #define CHROMEOS_ASH_COMPONENTS_NEARBY_PRESENCE_CREDENTIALS_LOCAL_DEVICE_DATA_PROVIDER_IMPL_H_
 
+#include "base/memory/raw_ptr.h"
 #include "chromeos/ash/components/nearby/presence/credentials/local_device_data_provider.h"
 #include "third_party/nearby/internal/proto/credential.pb.h"
 #include "third_party/nearby/internal/proto/metadata.pb.h"
@@ -38,6 +39,10 @@
   std::string GetAccountName() override;
   void SaveUserRegistrationInfo(const std::string& display_name,
                                 const std::string& image_url) override;
+
+ private:
+  PrefService* pref_service_ = nullptr;
+  const raw_ptr<signin::IdentityManager> identity_manager_;
 };
 
 }  // namespace ash::nearby::presence
diff --git a/chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl_unittest.cc b/chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl_unittest.cc
index 445410a9..d0c75d7 100644
--- a/chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl_unittest.cc
+++ b/chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl_unittest.cc
@@ -1,26 +1,43 @@
 // 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 <string>
 
 #include "chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl.h"
 
 #include "base/test/gtest_util.h"
 #include "base/test/task_environment.h"
 #include "chromeos/ash/components/nearby/presence/credentials/local_device_data_provider.h"
+#include "chromeos/ash/components/nearby/presence/credentials/prefs.h"
 #include "components/prefs/testing_pref_service.h"
 #include "components/signin/public/identity_manager/identity_test_environment.h"
 #include "components/signin/public/identity_manager/identity_test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+namespace {
+
+const std::string kUserEmail = "test.tester@gmail.com";
+const std::string kCanocalizedUserEmail = "testtester@gmail.com";
+
+}  // namespace
+
 namespace ash::nearby::presence {
 
 class LocalDeviceDataProviderImplTest : public testing::Test {
  public:
   void SetUp() override {
+    RegisterNearbyPresenceCredentialPrefs(pref_service_.registry());
+    identity_test_env_.MakePrimaryAccountAvailable(
+        kUserEmail, signin::ConsentLevel::kSignin);
+  }
+
+  void CreateDataProvider() {
     local_device_data_provider_ = std::make_unique<LocalDeviceDataProviderImpl>(
         &pref_service_, identity_test_env_.identity_manager());
   }
 
+  void DestroyDataProvider() { local_device_data_provider_.reset(); }
+
  protected:
   base::test::TaskEnvironment task_environment_;
   TestingPrefServiceSimple pref_service_;
@@ -28,8 +45,27 @@
   std::unique_ptr<LocalDeviceDataProvider> local_device_data_provider_;
 };
 
-TEST_F(LocalDeviceDataProviderImplTest, ObjectConstructionSuccess) {
-  ASSERT_TRUE(local_device_data_provider_);
+TEST_F(LocalDeviceDataProviderImplTest, DeviceId) {
+  CreateDataProvider();
+
+  // A 10-character alphanumeric ID is automatically generated if one doesn't
+  // already exist.
+  std::string id = local_device_data_provider_->GetDeviceId();
+  EXPECT_EQ(10u, id.size());
+  for (const char c : id) {
+    EXPECT_TRUE(std::isalnum(c));
+  }
+
+  // The ID is persisted.
+  DestroyDataProvider();
+  CreateDataProvider();
+  EXPECT_EQ(id, local_device_data_provider_->GetDeviceId());
+}
+
+TEST_F(LocalDeviceDataProviderImplTest, AccountName) {
+  CreateDataProvider();
+  EXPECT_EQ(kCanocalizedUserEmail,
+            local_device_data_provider_->GetAccountName());
 }
 
 }  // namespace ash::nearby::presence
diff --git a/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager.h b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager.h
new file mode 100644
index 0000000..674b0ae
--- /dev/null
+++ b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager.h
@@ -0,0 +1,40 @@
+// 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 CHROMEOS_ASH_COMPONENTS_NEARBY_PRESENCE_CREDENTIALS_NEARBY_PRESENCE_CREDENTIAL_MANAGER_H_
+#define CHROMEOS_ASH_COMPONENTS_NEARBY_PRESENCE_CREDENTIALS_NEARBY_PRESENCE_CREDENTIAL_MANAGER_H_
+
+#include "base/functional/callback_forward.h"
+
+namespace ash::nearby::presence {
+
+// The entry point for the credential web integration component. This class is
+// responsible for communicating with the Nearby Presence library to fetch,
+// save, and generate credentials. Exposed API's provide callers with
+// information about whether the user's local device has been registered with
+// the Nearby Presence server and the ability to trigger an immediate credential
+// upload/download. In addition,this class is responsible for daily credential
+// upload/downloads with the server.
+class NearbyPresenceCredentialManager {
+ public:
+  NearbyPresenceCredentialManager() = default;
+  virtual ~NearbyPresenceCredentialManager() = default;
+
+  // Returns whether this is this device has been registered with the server
+  // for NP before.
+  virtual bool IsLocalDeviceRegistered() = 0;
+
+  // Kicks off the first time initialization flow for registering presence
+  // with the Nearby Presence server. Returns the success of registration.
+  virtual void RegisterPresence(
+      base::OnceCallback<void(bool)> on_registered_callback) = 0;
+
+  // Schedules an immediate task to upload/download credentials to/from the
+  // server.
+  virtual void UpdateCredentials() = 0;
+};
+
+}  // namespace ash::nearby::presence
+
+#endif  // CHROMEOS_ASH_COMPONENTS_NEARBY_PRESENCE_CREDENTIALS_NEARBY_PRESENCE_CREDENTIAL_MANAGER_H_
diff --git a/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.cc b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.cc
new file mode 100644
index 0000000..4d1e8beb
--- /dev/null
+++ b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.cc
@@ -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.
+
+#include "chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.h"
+
+#include "base/functional/callback.h"
+#include "components/prefs/pref_service.h"
+#include "components/signin/public/identity_manager/identity_manager.h"
+
+namespace ash::nearby::presence {
+
+NearbyPresenceCredentialManagerImpl::NearbyPresenceCredentialManagerImpl(
+    PrefService* pref_service,
+    signin::IdentityManager* identity_manager) {
+  // TODO (b/276307539): Add mojo remote as a parameter once implemented.
+}
+
+NearbyPresenceCredentialManagerImpl::~NearbyPresenceCredentialManagerImpl() =
+    default;
+
+bool NearbyPresenceCredentialManagerImpl::IsLocalDeviceRegistered() {
+  // TODO (b/276307539): Implement `IsLocalDeviceRegistered`, this
+  // default implementation is to get the skeleton class to compile.
+  return false;
+}
+
+void NearbyPresenceCredentialManagerImpl::RegisterPresence(
+    base::OnceCallback<void(bool)> on_registered_callback) {
+  // TODO (b/276307539): Implement `RegisterPresence`.
+}
+
+void NearbyPresenceCredentialManagerImpl::UpdateCredentials() {
+  // TODO (b/276307539): Implement `UpdateCredentials`.
+}
+
+}  // namespace ash::nearby::presence
diff --git a/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.h b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.h
new file mode 100644
index 0000000..d44c47ae
--- /dev/null
+++ b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.h
@@ -0,0 +1,40 @@
+// 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 CHROMEOS_ASH_COMPONENTS_NEARBY_PRESENCE_CREDENTIALS_NEARBY_PRESENCE_CREDENTIAL_MANAGER_IMPL_H_
+#define CHROMEOS_ASH_COMPONENTS_NEARBY_PRESENCE_CREDENTIALS_NEARBY_PRESENCE_CREDENTIAL_MANAGER_IMPL_H_
+
+#include "chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager.h"
+
+class PrefService;
+
+namespace signin {
+class IdentityManager;
+}  // namespace signin
+
+namespace ash::nearby::presence {
+
+class NearbyPresenceCredentialManagerImpl
+    : public NearbyPresenceCredentialManager {
+ public:
+  NearbyPresenceCredentialManagerImpl(
+      PrefService* pref_service,
+      signin::IdentityManager* identity_manager);
+  ~NearbyPresenceCredentialManagerImpl() override;
+
+  NearbyPresenceCredentialManagerImpl(NearbyPresenceCredentialManagerImpl&) =
+      delete;
+  NearbyPresenceCredentialManagerImpl& operator=(
+      NearbyPresenceCredentialManagerImpl&) = delete;
+
+  // NearbyPresenceCredentialManager:
+  bool IsLocalDeviceRegistered() override;
+  void RegisterPresence(
+      base::OnceCallback<void(bool)> on_registered_callback) override;
+  void UpdateCredentials() override;
+};
+
+}  // namespace ash::nearby::presence
+
+#endif  // CHROMEOS_ASH_COMPONENTS_NEARBY_PRESENCE_CREDENTIALS_NEARBY_PRESENCE_CREDENTIAL_MANAGER_IMPL_H_
diff --git a/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl_unittest.cc b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl_unittest.cc
new file mode 100644
index 0000000..9468e65f
--- /dev/null
+++ b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl_unittest.cc
@@ -0,0 +1,34 @@
+// 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 "chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.h"
+#include "base/test/gtest_util.h"
+#include "base/test/task_environment.h"
+#include "chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager.h"
+#include "components/prefs/testing_pref_service.h"
+#include "components/signin/public/identity_manager/identity_test_environment.h"
+#include "components/signin/public/identity_manager/identity_test_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace ash::nearby::presence {
+
+class NearbyPresenceCredentialManagerImplTest : public testing::Test {
+ protected:
+  void SetUp() override {
+    credential_manager_ = std::make_unique<NearbyPresenceCredentialManagerImpl>(
+        &pref_service_, identity_test_env_.identity_manager());
+  }
+
+ protected:
+  base::test::TaskEnvironment task_environment_;
+  TestingPrefServiceSimple pref_service_;
+  signin::IdentityTestEnvironment identity_test_env_;
+  std::unique_ptr<NearbyPresenceCredentialManager> credential_manager_;
+};
+
+TEST_F(NearbyPresenceCredentialManagerImplTest, ObjectConstructionSuccess) {
+  ASSERT_TRUE(credential_manager_);
+}
+
+}  // namespace ash::nearby::presence
diff --git a/chromeos/ash/components/nearby/presence/credentials/prefs.cc b/chromeos/ash/components/nearby/presence/credentials/prefs.cc
new file mode 100644
index 0000000..3841be65
--- /dev/null
+++ b/chromeos/ash/components/nearby/presence/credentials/prefs.cc
@@ -0,0 +1,25 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromeos/ash/components/nearby/presence/credentials/prefs.h"
+
+#include "components/prefs/pref_registry.h"
+#include "components/prefs/pref_registry_simple.h"
+
+namespace ash::nearby::presence {
+
+namespace prefs {
+
+const char kNearbyPresenceDeviceIdPrefName[] =
+    "nearby_presence.local_device_id";
+
+}  // namespace prefs
+
+void RegisterNearbyPresenceCredentialPrefs(PrefRegistrySimple* registry) {
+  // These prefs are not synced across devices on purpose.
+  registry->RegisterStringPref(prefs::kNearbyPresenceDeviceIdPrefName,
+                               /*default_value=*/std::string());
+}
+
+}  // namespace ash::nearby::presence
diff --git a/chromeos/ash/components/nearby/presence/credentials/prefs.h b/chromeos/ash/components/nearby/presence/credentials/prefs.h
new file mode 100644
index 0000000..2d5328fa
--- /dev/null
+++ b/chromeos/ash/components/nearby/presence/credentials/prefs.h
@@ -0,0 +1,22 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_ASH_COMPONENTS_NEARBY_PRESENCE_CREDENTIALS_PREFS_H_
+#define CHROMEOS_ASH_COMPONENTS_NEARBY_PRESENCE_CREDENTIALS_PREFS_H_
+
+class PrefRegistrySimple;
+
+namespace ash::nearby::presence {
+
+namespace prefs {
+
+extern const char kNearbyPresenceDeviceIdPrefName[];
+
+}  // namespace prefs
+
+void RegisterNearbyPresenceCredentialPrefs(PrefRegistrySimple* registry);
+
+}  // namespace ash::nearby::presence
+
+#endif  // CHROMEOS_ASH_COMPONENTS_NEARBY_PRESENCE_CREDENTIALS_PREFS_H_
diff --git a/chromeos/ash/components/phonehub/app_stream_launcher_data_model_unittest.cc b/chromeos/ash/components/phonehub/app_stream_launcher_data_model_unittest.cc
index f857da29..65e936e8 100644
--- a/chromeos/ash/components/phonehub/app_stream_launcher_data_model_unittest.cc
+++ b/chromeos/ash/components/phonehub/app_stream_launcher_data_model_unittest.cc
@@ -9,8 +9,7 @@
 #include "chromeos/ash/components/phonehub/notification.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace ash {
-namespace phonehub {
+namespace ash::phonehub {
 
 namespace {
 
@@ -128,12 +127,16 @@
 
 TEST_F(AppStreamLauncherDataModelTest, SetAppsList) {
   std::vector<Notification::AppMetadata> apps_list;
-  apps_list.emplace_back(Notification::AppMetadata(
-      u"GPay", "com.fakeapp1", gfx::Image(), absl::nullopt, true, 1,
-      proto::AppStreamabilityStatus::STREAMABLE));
-  apps_list.emplace_back(Notification::AppMetadata(
-      u"Gboard", "com.fakeapp2", gfx::Image(), absl::nullopt, true, 1,
-      proto::AppStreamabilityStatus::STREAMABLE));
+  apps_list.emplace_back(u"GPay", "com.fakeapp1", /*color_icon=*/gfx::Image(),
+                         /*monochrome_icon_mask=*/absl::nullopt,
+                         /*icon_color=*/absl::nullopt,
+                         /*icon_is_monochrome=*/true, /*user_id=*/1,
+                         proto::AppStreamabilityStatus::STREAMABLE);
+  apps_list.emplace_back(u"Gboard", "com.fakeapp2", /*color_icon=*/gfx::Image(),
+                         /*monochrome_icon_mask=*/absl::nullopt,
+                         /*icon_color=*/absl::nullopt,
+                         /*icon_is_monochrome=*/true, /*user_id=*/1,
+                         proto::AppStreamabilityStatus::STREAMABLE);
   SetAppList(apps_list);
   EXPECT_TRUE(IsObserverAppListChanged());
   EXPECT_EQ(GetAppsList()->size(), 2u);
@@ -146,26 +149,26 @@
 
 TEST_F(AppStreamLauncherDataModelTest, AddAppToList) {
   std::vector<Notification::AppMetadata> apps_list;
-  apps_list.emplace_back(Notification::AppMetadata(
-      u"GPay", "com.fakeapp1", /*color_icon=*/gfx::Image(),
-      /*monochrome_icon_mask=*/absl::nullopt,
-      /*icon_color*/ absl::nullopt, /*icon_is_monochrome*/ true, /*user_id=*/1,
-      proto::AppStreamabilityStatus::STREAMABLE));
-  apps_list.emplace_back(Notification::AppMetadata(
-      u"Gboard", "com.fakeapp2", /*color_icon=*/gfx::Image(),
-      /*monochrome_icon_mask=*/absl::nullopt,
-      /*icon_color*/ absl::nullopt, /*icon_is_monochrome*/ true, /*user_id=*/1,
-      proto::AppStreamabilityStatus::STREAMABLE));
+  apps_list.emplace_back(u"GPay", "com.fakeapp1", /*color_icon=*/gfx::Image(),
+                         /*monochrome_icon_mask=*/absl::nullopt,
+                         /*icon_color=*/absl::nullopt,
+                         /*icon_is_monochrome=*/true, /*user_id=*/1,
+                         proto::AppStreamabilityStatus::STREAMABLE);
+  apps_list.emplace_back(u"Gboard", "com.fakeapp2", /*color_icon=*/gfx::Image(),
+                         /*monochrome_icon_mask=*/absl::nullopt,
+                         /*icon_color=*/absl::nullopt,
+                         /*icon_is_monochrome=*/true, /*user_id=*/1,
+                         proto::AppStreamabilityStatus::STREAMABLE);
   SetAppList(apps_list);
   AddAppToList(Notification::AppMetadata(
       u"added_app", "com.fakeapp3", /*color_icon=*/gfx::Image(),
-      /*monochrome_icon_mask=*/absl::nullopt, /*icon_color*/ absl::nullopt,
-      /*icon_is_monochrome*/ true, /*user_id=*/1,
+      /*monochrome_icon_mask=*/absl::nullopt, /*icon_color=*/absl::nullopt,
+      /*icon_is_monochrome=*/true, /*user_id=*/1,
       proto::AppStreamabilityStatus::STREAMABLE));
   AddAppToList(Notification::AppMetadata(
       u"a_added_app", "com.fakeapp3", /*color_icon=*/gfx::Image(),
-      /*monochrome_icon_mask=*/absl::nullopt, /*icon_color*/ absl::nullopt,
-      /*icon_is_monochrome*/ true, /*user_id=*/1,
+      /*monochrome_icon_mask=*/absl::nullopt, /*icon_color=*/absl::nullopt,
+      /*icon_is_monochrome=*/true, /*user_id=*/1,
       proto::AppStreamabilityStatus::STREAMABLE));
   EXPECT_TRUE(IsObserverAppListChanged());
   EXPECT_EQ(GetAppsList()->size(), 4u);
@@ -182,16 +185,16 @@
 
 TEST_F(AppStreamLauncherDataModelTest, RemoveAppFromList) {
   std::vector<Notification::AppMetadata> apps_list;
-  apps_list.emplace_back(Notification::AppMetadata(
-      u"GPay", "com.fakeapp1", /*color_icon=*/gfx::Image(),
-      /*monochrome_icon_mask=*/absl::nullopt,
-      /*icon_color*/ absl::nullopt, /*icon_is_monochrome*/ true, /*user_id=*/1,
-      proto::AppStreamabilityStatus::STREAMABLE));
-  apps_list.emplace_back(Notification::AppMetadata(
-      u"Gboard", "com.fakeapp2", /*color_icon=*/gfx::Image(),
-      /*monochrome_icon_mask=*/absl::nullopt,
-      /*icon_color*/ absl::nullopt, /*icon_is_monochrome*/ true, /*user_id=*/1,
-      proto::AppStreamabilityStatus::STREAMABLE));
+  apps_list.emplace_back(u"GPay", "com.fakeapp1", /*color_icon=*/gfx::Image(),
+                         /*monochrome_icon_mask=*/absl::nullopt,
+                         /*icon_color=*/absl::nullopt,
+                         /*icon_is_monochrome=*/true, /*user_id=*/1,
+                         proto::AppStreamabilityStatus::STREAMABLE);
+  apps_list.emplace_back(u"Gboard", "com.fakeapp2", /*color_icon=*/gfx::Image(),
+                         /*monochrome_icon_mask=*/absl::nullopt,
+                         /*icon_color=*/absl::nullopt,
+                         /*icon_is_monochrome=*/true, /*user_id=*/1,
+                         proto::AppStreamabilityStatus::STREAMABLE);
   SetAppList(apps_list);
   auto app_to_remove = proto::App();
   app_to_remove.set_package_name("com.fakeapp1");
@@ -209,5 +212,5 @@
   EXPECT_EQ(GetLauncherHeight(), 400);
   EXPECT_EQ(GetLauncherWidth(), 300);
 }
-}  // namespace phonehub
-}  // namespace ash
+
+}  // namespace ash::phonehub
diff --git a/chromeos/ash/components/phonehub/recent_apps_interaction_handler_impl_unittest.cc b/chromeos/ash/components/phonehub/recent_apps_interaction_handler_impl_unittest.cc
index 17f0dd6..e4a857f9f5 100644
--- a/chromeos/ash/components/phonehub/recent_apps_interaction_handler_impl_unittest.cc
+++ b/chromeos/ash/components/phonehub/recent_apps_interaction_handler_impl_unittest.cc
@@ -353,18 +353,18 @@
 
 TEST_F(RecentAppsInteractionHandlerTest, SetStreamableApps) {
   std::vector<Notification::AppMetadata> streamable_apps;
-  streamable_apps.emplace_back(Notification::AppMetadata(
-      u"App1", "com.fakeapp1", /*color_icon=*/gfx::Image(),
-      /*monochrome_icon_mask=*/absl::nullopt,
-      /*icon_color=*/absl::nullopt,
-      /*icon_is_monochrome=*/true, 1,
-      proto::AppStreamabilityStatus::STREAMABLE));
-  streamable_apps.emplace_back(Notification::AppMetadata(
-      u"App2", "com.fakeapp2", /*color_icon=*/gfx::Image(),
-      /*monochrome_icon_mask=*/gfx::Image(),
-      /*icon_color=*/absl::nullopt,
-      /*icon_is_monochrome=*/true, 1,
-      proto::AppStreamabilityStatus::STREAMABLE));
+  streamable_apps.emplace_back(u"App1", "com.fakeapp1",
+                               /*color_icon=*/gfx::Image(),
+                               /*monochrome_icon_mask=*/absl::nullopt,
+                               /*icon_color=*/absl::nullopt,
+                               /*icon_is_monochrome=*/true, 1,
+                               proto::AppStreamabilityStatus::STREAMABLE);
+  streamable_apps.emplace_back(u"App2", "com.fakeapp2",
+                               /*color_icon=*/gfx::Image(),
+                               /*monochrome_icon_mask=*/gfx::Image(),
+                               /*icon_color=*/absl::nullopt,
+                               /*icon_is_monochrome=*/true, 1,
+                               proto::AppStreamabilityStatus::STREAMABLE);
 
   handler().SetStreamableApps(streamable_apps);
 
@@ -382,18 +382,18 @@
 TEST_F(RecentAppsInteractionHandlerTest,
        SetStreamableApps_ClearsPreviousState) {
   std::vector<Notification::AppMetadata> streamable_apps;
-  streamable_apps.emplace_back(Notification::AppMetadata(
-      u"App1", "com.fakeapp1", /*color_icon=*/gfx::Image(),
-      /*monochrome_icon_mask=*/absl::nullopt,
-      /*icon_color=*/absl::nullopt,
-      /*icon_is_monochrome=*/true, 1,
-      proto::AppStreamabilityStatus::STREAMABLE));
-  streamable_apps.emplace_back(Notification::AppMetadata(
-      u"App2", "com.fakeapp2", /*color_icon=*/gfx::Image(),
-      /*monochrome_icon_mask=*/gfx::Image(),
-      /*icon_color=*/absl::nullopt,
-      /*icon_is_monochrome=*/true, 1,
-      proto::AppStreamabilityStatus::STREAMABLE));
+  streamable_apps.emplace_back(u"App1", "com.fakeapp1",
+                               /*color_icon=*/gfx::Image(),
+                               /*monochrome_icon_mask=*/absl::nullopt,
+                               /*icon_color=*/absl::nullopt,
+                               /*icon_is_monochrome=*/true, 1,
+                               proto::AppStreamabilityStatus::STREAMABLE);
+  streamable_apps.emplace_back(u"App2", "com.fakeapp2",
+                               /*color_icon=*/gfx::Image(),
+                               /*monochrome_icon_mask=*/gfx::Image(),
+                               /*icon_color=*/absl::nullopt,
+                               /*icon_is_monochrome=*/true, 1,
+                               proto::AppStreamabilityStatus::STREAMABLE);
 
   handler().SetStreamableApps(streamable_apps);
 
@@ -408,12 +408,12 @@
                                 .first.package_name);
 
   std::vector<Notification::AppMetadata> streamable_apps2;
-  streamable_apps2.emplace_back(Notification::AppMetadata(
-      u"App3", "com.fakeapp3", /*color_icon=*/gfx::Image(),
-      /*monochrome_icon_mask=*/absl::nullopt,
-      /*icon_color=*/absl::nullopt,
-      /*icon_is_monochrome=*/true, 1,
-      proto::AppStreamabilityStatus::STREAMABLE));
+  streamable_apps2.emplace_back(u"App3", "com.fakeapp3",
+                                /*color_icon=*/gfx::Image(),
+                                /*monochrome_icon_mask=*/absl::nullopt,
+                                /*icon_color=*/absl::nullopt,
+                                /*icon_is_monochrome=*/true, 1,
+                                proto::AppStreamabilityStatus::STREAMABLE);
 
   handler().SetStreamableApps(streamable_apps2);
 
@@ -434,18 +434,18 @@
 
 TEST_F(RecentAppsInteractionHandlerTest, RemoveStreamableApp) {
   std::vector<Notification::AppMetadata> streamable_apps;
-  streamable_apps.emplace_back(Notification::AppMetadata(
-      u"App1", "com.fakeapp1", /*color_icon=*/gfx::Image(),
-      /*monochrome_icon_mask=*/absl::nullopt,
-      /*icon_color=*/absl::nullopt,
-      /*icon_is_monochrome=*/true, 1,
-      proto::AppStreamabilityStatus::STREAMABLE));
-  streamable_apps.emplace_back(Notification::AppMetadata(
-      u"App2", "com.fakeapp2", /*color_icon=*/gfx::Image(),
-      /*monochrome_icon_mask=*/gfx::Image(),
-      /*icon_color=*/absl::nullopt,
-      /*icon_is_monochrome=*/true, 1,
-      proto::AppStreamabilityStatus::STREAMABLE));
+  streamable_apps.emplace_back(u"App1", "com.fakeapp1",
+                               /*color_icon=*/gfx::Image(),
+                               /*monochrome_icon_mask=*/absl::nullopt,
+                               /*icon_color=*/absl::nullopt,
+                               /*icon_is_monochrome=*/true, 1,
+                               proto::AppStreamabilityStatus::STREAMABLE);
+  streamable_apps.emplace_back(u"App2", "com.fakeapp2",
+                               /*color_icon=*/gfx::Image(),
+                               /*monochrome_icon_mask=*/gfx::Image(),
+                               /*icon_color=*/absl::nullopt,
+                               /*icon_is_monochrome=*/true, 1,
+                               proto::AppStreamabilityStatus::STREAMABLE);
 
   handler().SetStreamableApps(streamable_apps);
 
diff --git a/chromeos/ash/components/proximity_auth/metrics.cc b/chromeos/ash/components/proximity_auth/metrics.cc
index b942bc7..a819dc1 100644
--- a/chromeos/ash/components/proximity_auth/metrics.cc
+++ b/chromeos/ash/components/proximity_auth/metrics.cc
@@ -9,7 +9,6 @@
 #include <algorithm>
 
 #include "base/check_op.h"
-#include "base/cxx17_backports.h"
 #include "base/hash/md5.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
@@ -50,7 +49,7 @@
 
 void RecordAuthProximityRollingRssi(int rolling_rssi) {
   if (rolling_rssi != kUnknownProximityValue)
-    rolling_rssi = base::clamp(rolling_rssi, -100, 50);
+    rolling_rssi = std::clamp(rolling_rssi, -100, 50);
 
   base::UmaHistogramSparse("EasyUnlock.AuthProximity.RollingRssi",
                            rolling_rssi);
diff --git a/chromeos/ash/components/tether/device_status_util.cc b/chromeos/ash/components/tether/device_status_util.cc
index d440ef86..ffe72b6 100644
--- a/chromeos/ash/components/tether/device_status_util.cc
+++ b/chromeos/ash/components/tether/device_status_util.cc
@@ -4,7 +4,7 @@
 
 #include "chromeos/ash/components/tether/device_status_util.h"
 
-#include "base/cxx17_backports.h"
+#include <algorithm>
 
 namespace ash {
 
@@ -31,7 +31,7 @@
   if (battery_percentage_out) {
     *battery_percentage_out =
         status.has_battery_percentage()
-            ? base::clamp(status.battery_percentage(), 0, 100)
+            ? std::clamp(status.battery_percentage(), 0, 100)
             : 100;
   }
   if (signal_strength_out) {
@@ -42,8 +42,8 @@
     constexpr int32_t kConversionFactor = 100 / 4;
     *signal_strength_out =
         status.has_connection_strength()
-            ? base::clamp(kConversionFactor * status.connection_strength(), 0,
-                          100)
+            ? std::clamp(kConversionFactor * status.connection_strength(), 0,
+                         100)
             : 100;
   }
 }
diff --git a/chromeos/ash/services/assistant/assistant_manager_service_impl_unittest.cc b/chromeos/ash/services/assistant/assistant_manager_service_impl_unittest.cc
index a8b35977..49179e7e 100644
--- a/chromeos/ash/services/assistant/assistant_manager_service_impl_unittest.cc
+++ b/chromeos/ash/services/assistant/assistant_manager_service_impl_unittest.cc
@@ -188,6 +188,10 @@
 
   FullyInitializedAssistantState& assistant_state() { return assistant_state_; }
 
+  void SetAssistantStateContext(bool enabled) {
+    assistant_state_.SetContextEnabled(enabled);
+  }
+
   FakeServiceContext* fake_service_context() { return service_context_.get(); }
 
   base::test::TaskEnvironment& task_environment() { return task_environment_; }
@@ -759,4 +763,18 @@
   EXPECT_TRUE(mojom_service_controller().dark_mode_enabled().value());
 }
 
+TEST_F(AssistantManagerServiceImplTest, ShouldNotCrashRunningAfterStopped) {
+  Start();
+  SetAssistantStateContext(/*enabled=*/false);
+  WaitForState(AssistantManagerService::STARTED);
+
+  // http://crbug.com/1414264: calling Stop() before Running is set, should not
+  // crash.
+  assistant_manager_service()->Stop();
+  WaitForState(AssistantManagerService::STOPPING);
+
+  mojom_service_controller().SetState(ServiceState::kRunning);
+  WaitForState(AssistantManagerService::RUNNING);
+}
+
 }  // namespace ash::assistant
diff --git a/chromeos/ash/services/assistant/media_host.cc b/chromeos/ash/services/assistant/media_host.cc
index f4e8310..8ad3168 100644
--- a/chromeos/ash/services/assistant/media_host.cc
+++ b/chromeos/ash/services/assistant/media_host.cc
@@ -237,11 +237,17 @@
 }
 
 void MediaHost::ResumeInternalMediaPlayer() {
-  libassistant_media_controller().ResumeInternalMediaPlayer();
+  if (!libassistant_media_controller_) {
+    return;
+  }
+  libassistant_media_controller_->ResumeInternalMediaPlayer();
 }
 
 void MediaHost::PauseInternalMediaPlayer() {
-  libassistant_media_controller().PauseInternalMediaPlayer();
+  if (!libassistant_media_controller_) {
+    return;
+  }
+  libassistant_media_controller_->PauseInternalMediaPlayer();
 }
 
 void MediaHost::SetRelatedInfoEnabled(bool enable) {
@@ -253,13 +259,6 @@
   }
 }
 
-libassistant::mojom::MediaController&
-MediaHost::libassistant_media_controller() {
-  // Initialize must be called first.
-  DCHECK(libassistant_media_controller_);
-  return *libassistant_media_controller_;
-}
-
 void MediaHost::UpdateMediaState(
     const base::UnguessableToken& media_session_id,
     libassistant::mojom::MediaStatePtr media_state) {
@@ -271,12 +270,18 @@
     return;
   }
 
-  libassistant_media_controller().SetExternalPlaybackState(
+  if (!libassistant_media_controller_) {
+    return;
+  }
+  libassistant_media_controller_->SetExternalPlaybackState(
       std::move(media_state));
 }
 
 void MediaHost::ResetMediaState() {
-  libassistant_media_controller().SetExternalPlaybackState(
+  if (!libassistant_media_controller_) {
+    return;
+  }
+  libassistant_media_controller_->SetExternalPlaybackState(
       libassistant::mojom::MediaState::New());
 }
 
diff --git a/chromeos/ash/services/assistant/media_host.h b/chromeos/ash/services/assistant/media_host.h
index 02faae02..7c84023 100644
--- a/chromeos/ash/services/assistant/media_host.h
+++ b/chromeos/ash/services/assistant/media_host.h
@@ -56,8 +56,6 @@
   class LibassistantMediaDelegate;
   class ChromeosMediaStateObserver;
 
-  libassistant::mojom::MediaController& libassistant_media_controller();
-
   void UpdateMediaState(const base::UnguessableToken& media_session_id,
                         libassistant::mojom::MediaStatePtr media_state);
   void ResetMediaState();
diff --git a/chromeos/ash/services/assistant/test_support/fake_service_controller.cc b/chromeos/ash/services/assistant/test_support/fake_service_controller.cc
index c1f22f8..9047f8fc 100644
--- a/chromeos/ash/services/assistant/test_support/fake_service_controller.cc
+++ b/chromeos/ash/services/assistant/test_support/fake_service_controller.cc
@@ -92,7 +92,13 @@
 }
 
 void FakeServiceController::Stop() {
-  SetState(State::kStopped);
+  // Post a delayed task to make it possible to set other state between
+  // kStopping and kStopped.
+  base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
+      FROM_HERE,
+      base::BindOnce(&FakeServiceController::SetState,
+                     weak_factory_.GetWeakPtr(), State::kStopped),
+      base::Milliseconds(1));
 }
 
 void FakeServiceController::ResetAllDataAndStop() {
diff --git a/chromeos/ash/services/assistant/test_support/fully_initialized_assistant_state.cc b/chromeos/ash/services/assistant/test_support/fully_initialized_assistant_state.cc
index 04f2c30..1df9168 100644
--- a/chromeos/ash/services/assistant/test_support/fully_initialized_assistant_state.cc
+++ b/chromeos/ash/services/assistant/test_support/fully_initialized_assistant_state.cc
@@ -17,6 +17,10 @@
     observer.OnAssistantSettingsEnabled(settings_enabled_.value());
 }
 
+void FullyInitializedAssistantState::SetContextEnabled(bool enabled) {
+  context_enabled_ = enabled;
+}
+
 void FullyInitializedAssistantState::InitializeAllValues() {
   settings_enabled_ = true;
   consent_status_ = prefs::ConsentStatus::kActivityControlAccepted;
diff --git a/chromeos/ash/services/assistant/test_support/fully_initialized_assistant_state.h b/chromeos/ash/services/assistant/test_support/fully_initialized_assistant_state.h
index 0fb499bf..c14400e 100644
--- a/chromeos/ash/services/assistant/test_support/fully_initialized_assistant_state.h
+++ b/chromeos/ash/services/assistant/test_support/fully_initialized_assistant_state.h
@@ -24,6 +24,8 @@
 
   void SetAssistantEnabled(bool enabled);
 
+  void SetContextEnabled(bool enabled);
+
  private:
   void InitializeAllValues();
 };
diff --git a/components/autofill/core/browser/autofill_test_utils.cc b/components/autofill/core/browser/autofill_test_utils.cc
index e504a835..c9ca8de 100644
--- a/components/autofill/core/browser/autofill_test_utils.cc
+++ b/components/autofill/core/browser/autofill_test_utils.cc
@@ -569,9 +569,16 @@
   }
 }
 
+std::string GetStrippedValue(const char* value) {
+  std::u16string stripped_value;
+  base::RemoveChars(base::UTF8ToUTF16(value), base::kWhitespaceUTF16,
+                    &stripped_value);
+  return base::UTF16ToUTF8(stripped_value);
+}
+
 IBAN GetIBAN() {
   IBAN iban(base::GenerateUuid());
-  iban.set_value(u"DE91 1000 0000 0123 4567 89");
+  iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue)));
   iban.set_nickname(u"Nickname for Iban");
   return iban;
 }
diff --git a/components/autofill/core/browser/autofill_test_utils.h b/components/autofill/core/browser/autofill_test_utils.h
index e48976b..72b9688 100644
--- a/components/autofill/core/browser/autofill_test_utils.h
+++ b/components/autofill/core/browser/autofill_test_utils.h
@@ -171,6 +171,11 @@
                            bool ignore_status = false);
 
 const char kEmptyOrigin[] = "";
+// A valid France IBAN number.
+const char kIbanValue[] = "FR76 3000 6000 0112 3456 7890 189";
+// Two valid Switzerland IBAN numbers.
+const char kIbanValue_1[] = "CH56 0483 5012 3456 7800 9";
+const char kIbanValue_2[] = "CH93 0076 2011 6238 5295 7";
 
 // The following methods return a PrefService that can be used for
 // Autofill-related testing in contexts where the PrefService would otherwise
@@ -259,9 +264,8 @@
 // Populates `form_data` with data corresponding to an IBAN form (a form with a
 // single IBAN field). Note that this actually appends fields to the form data,
 // which can be useful for building up more complex test forms.
-void CreateTestIbanFormData(
-    FormData* form_data,
-    const char* value = "FR76 3000 6000 0112 3456 7890 189");
+void CreateTestIbanFormData(FormData* form_data,
+                            const char* value = kIbanValue);
 
 // Strips those members from |form| and |field| that are not serialized via
 // mojo, i.e., resets them to `{}`.
@@ -300,6 +304,10 @@
     AutofillProfile& profile,
     autofill_metrics::AutofillProfileSourceCategory category);
 
+// Returns the stripped (without characters representing whitespace) value of
+// the given `value`.
+std::string GetStrippedValue(const char* value);
+
 // Returns an IBAN full of dummy info.
 IBAN GetIBAN();
 
diff --git a/components/autofill/core/browser/form_data_importer_unittest.cc b/components/autofill/core/browser/form_data_importer_unittest.cc
index 3c17170..d88d377 100644
--- a/components/autofill/core/browser/form_data_importer_unittest.cc
+++ b/components/autofill/core/browser/form_data_importer_unittest.cc
@@ -115,12 +115,6 @@
 constexpr char kDefaultCreditCardExpMonth[] = "01";
 constexpr char kDefaultCreditCardExpYear[] = "2999";
 
-#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
-// Define default value for Iban.
-constexpr char kIbanValue[] = "FR76 3000 6000 0112 3456 7890 189";
-constexpr char kIbanValueWithoutWhitespaces[] = "FR7630006000011234567890189";
-#endif  // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
-
 // For a given ServerFieldType |type| returns a pair of field name and label
 // that should be parsed into this type by our field type parsers.
 std::pair<std::string, std::string> GetLabelAndNameForType(
@@ -3198,7 +3192,7 @@
 
 TEST_P(FormDataImporterTest, ExtractFormData_ImportIbanRecordType_LocalIban) {
   IBAN iban;
-  iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue)));
+  iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue)));
   personal_data_manager_->AddIBAN(iban);
 
   WaitForOnPersonalDataChanged();
@@ -4390,7 +4384,7 @@
 TEST_P(FormDataImporterTest,
        ExtractFormData_ProcessIBANImportCandidate_LocalIban) {
   IBAN iban;
-  iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue)));
+  iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue)));
   personal_data_manager_->AddIBAN(iban);
 
   WaitForOnPersonalDataChanged();
@@ -4415,7 +4409,8 @@
 
   iban_save_strike_database.AddStrikes(
       iban_save_strike_database.GetMaxStrikesLimit(),
-      IBANSaveManager::GetPartialIbanHashString(kIbanValueWithoutWhitespaces));
+      IBANSaveManager::GetPartialIbanHashString(
+          test::GetStrippedValue(test::kIbanValue)));
 
   // Simulate a form submission with a new IBAN.
   FormData form;
diff --git a/components/autofill/core/browser/iban_manager_unittest.cc b/components/autofill/core/browser/iban_manager_unittest.cc
index eca1d277..1eb46cb 100644
--- a/components/autofill/core/browser/iban_manager_unittest.cc
+++ b/components/autofill/core/browser/iban_manager_unittest.cc
@@ -29,14 +29,8 @@
 
 namespace autofill {
 
-// Valid Ireland IBAN number.
-constexpr char16_t kIbanValue_0[] = u"FR76 3000 6000 0112 3456 7890 189";
-// Two valid Switzerland IBAN numbers.
-constexpr char16_t kIbanValue_1[] = u"CH56 0483 5012 3456 7800 9";
-constexpr char16_t kIbanValue_2[] = u"CH93 0076 2011 6238 5295 7";
-
-constexpr char16_t kNickname_0[] = u"Nickname 0";
-constexpr char16_t kNickname_1[] = u"Nickname 1";
+constexpr char kNickname_0[] = "Nickname 0";
+constexpr char kNickname_1[] = "Nickname 1";
 
 namespace {
 
@@ -91,12 +85,12 @@
   }
 
   // Sets up the TestPersonalDataManager with an IBAN.
-  IBAN SetUpIBAN(base::StringPiece16 value, base::StringPiece16 nickname) {
+  IBAN SetUpIBAN(base::StringPiece value, base::StringPiece nickname) {
     IBAN iban;
     std::string guid = base::GenerateUuid();
     iban.set_guid(guid);
-    iban.set_value(std::u16string(value));
-    iban.set_nickname(std::u16string(nickname));
+    iban.set_value(base::UTF8ToUTF16(std::string(value)));
+    iban.set_nickname(base::UTF8ToUTF16(std::string(nickname)));
     personal_data_manager_.AddIBANForTest(std::make_unique<IBAN>(iban));
     return iban;
   }
@@ -117,8 +111,8 @@
 
   // Sets up the TestPersonalDataManager with an IBAN and corresponding
   // suggestion.
-  Suggestion SetUpIBANAndSuggestion(base::StringPiece16 value,
-                                    base::StringPiece16 nickname) {
+  Suggestion SetUpIBANAndSuggestion(base::StringPiece value,
+                                    base::StringPiece nickname) {
     IBAN iban = SetUpIBAN(value, nickname);
     Suggestion iban_suggestion(iban.GetIdentifierStringForAutofillDisplay());
     iban_suggestion.frontend_id = POPUP_ITEM_ID_IBAN_ENTRY;
@@ -157,9 +151,9 @@
 
 TEST_F(IBANManagerTest, ShowsIBANSuggestions) {
   Suggestion iban_suggestion_0 =
-      SetUpIBANAndSuggestion(kIbanValue_0, kNickname_0);
+      SetUpIBANAndSuggestion(test::kIbanValue, kNickname_0);
   Suggestion iban_suggestion_1 =
-      SetUpIBANAndSuggestion(kIbanValue_1, kNickname_1);
+      SetUpIBANAndSuggestion(test::kIbanValue_1, kNickname_1);
 
   AutofillField test_field;
   SuggestionsContext context = GetIbanFocusedSuggestionsContext(test_field);
@@ -185,8 +179,8 @@
 
 TEST_F(IBANManagerTest, PaymentsAutofillEnabledPrefOff_NoIbanSuggestionsShown) {
   personal_data_manager_.SetAutofillCreditCardEnabled(false);
-  SetUpIBANAndSuggestion(kIbanValue_0, kNickname_0);
-  SetUpIBANAndSuggestion(kIbanValue_1, kNickname_1);
+  SetUpIBANAndSuggestion(test::kIbanValue, kNickname_0);
+  SetUpIBANAndSuggestion(test::kIbanValue_1, kNickname_1);
 
   AutofillField test_field;
   SuggestionsContext context = GetIbanFocusedSuggestionsContext(test_field);
@@ -203,7 +197,7 @@
 
 TEST_F(IBANManagerTest, IBANSuggestions_SeparatorAndFooter) {
   Suggestion iban_suggestion_0 =
-      SetUpIBANAndSuggestion(kIbanValue_0, kNickname_0);
+      SetUpIBANAndSuggestion(test::kIbanValue, kNickname_0);
   Suggestion iban_suggestion_1 = SetUpSeparator();
   Suggestion iban_suggestion_2 = SetUpFooterManagePaymentMethods();
 
@@ -233,12 +227,12 @@
 
 TEST_F(IBANManagerTest, ShowsIBANSuggestions_NoSuggestion) {
   Suggestion iban_suggestion_0 =
-      SetUpIBANAndSuggestion(kIbanValue_0, kNickname_0);
+      SetUpIBANAndSuggestion(test::kIbanValue, kNickname_0);
   Suggestion iban_suggestion_1 =
-      SetUpIBANAndSuggestion(kIbanValue_1, kNickname_1);
+      SetUpIBANAndSuggestion(test::kIbanValue_1, kNickname_1);
 
   AutofillField test_field;
-  test_field.value = std::u16string(kIbanValue_0);
+  test_field.value = base::UTF8ToUTF16(std::string(test::kIbanValue));
   SuggestionsContext context = GetIbanFocusedSuggestionsContext(test_field);
 
   // Verify that `OnSuggestionsReturned` handler is not triggered any IBAN-based
@@ -256,9 +250,9 @@
 
 TEST_F(IBANManagerTest, ShowsIBANSuggestions_OnlyPrefixMatch) {
   Suggestion iban_suggestion_0 =
-      SetUpIBANAndSuggestion(kIbanValue_1, kNickname_0);
+      SetUpIBANAndSuggestion(test::kIbanValue_1, kNickname_0);
   Suggestion iban_suggestion_1 =
-      SetUpIBANAndSuggestion(kIbanValue_2, kNickname_1);
+      SetUpIBANAndSuggestion(test::kIbanValue_2, kNickname_1);
   Suggestion iban_suggestion_2 = SetUpSeparator();
   Suggestion iban_suggestion_3 = SetUpFooterManagePaymentMethods();
 
@@ -327,7 +321,7 @@
 }
 
 TEST_F(IBANManagerTest, DoesNotShowIBANsForBlockedWebsite) {
-  SetUpIBAN(kIbanValue_0, kNickname_0);
+  SetUpIBAN(test::kIbanValue, kNickname_0);
   AutofillField test_field;
   SuggestionsContext context = GetIbanFocusedSuggestionsContext(test_field);
 
@@ -351,7 +345,7 @@
 // suggestions cannot and will not be blocked.
 TEST_F(IBANManagerTest, ShowsIBANSuggestions_OptimizationGuideNotPresent) {
   Suggestion iban_suggestion_0 =
-      SetUpIBANAndSuggestion(kIbanValue_0, kNickname_0);
+      SetUpIBANAndSuggestion(test::kIbanValue, kNickname_0);
   AutofillField test_field;
   SuggestionsContext context = GetIbanFocusedSuggestionsContext(test_field);
 
@@ -377,10 +371,10 @@
 }
 
 TEST_F(IBANManagerTest, NotIbanFieldFocused_NoSuggestionsShown) {
-  SetUpIBAN(kIbanValue_0, kNickname_0);
+  SetUpIBAN(test::kIbanValue, kNickname_0);
 
   AutofillField test_field;
-  test_field.value = std::u16string(kIbanValue_0);
+  test_field.value = base::UTF8ToUTF16(std::string(test::kIbanValue));
   // Set the field type to any type than "IBAN_VALUE".
   SuggestionsContext context = GetIbanFocusedSuggestionsContext(
       test_field, CREDIT_CARD_VERIFICATION_CODE);
@@ -400,7 +394,7 @@
 // logged correctly.
 TEST_F(IBANManagerTest, Metrics_SuggestionsShown) {
   base::HistogramTester histogram_tester;
-  SetUpIBAN(kIbanValue_0, kNickname_0);
+  SetUpIBAN(test::kIbanValue, kNickname_0);
 
   AutofillField test_field;
   test_field.unique_renderer_id = test::MakeFieldRendererId();
@@ -429,9 +423,9 @@
 // are logged correctly.
 TEST_F(IBANManagerTest, Metrics_SuggestionSelected) {
   base::HistogramTester histogram_tester;
-  SetUpIBAN(kIbanValue_0, kNickname_0);
-  SetUpIBAN(kIbanValue_1, kNickname_1);
-  SetUpIBAN(kIbanValue_2, u"");
+  SetUpIBAN(test::kIbanValue, kNickname_0);
+  SetUpIBAN(test::kIbanValue_1, kNickname_1);
+  SetUpIBAN(test::kIbanValue_2, "");
 
   AutofillField test_field;
   test_field.unique_renderer_id = test::MakeFieldRendererId();
@@ -465,8 +459,8 @@
 
 TEST_F(IBANManagerTest, Metrics_NoSuggestionShown) {
   base::HistogramTester histogram_tester;
-  SetUpIBAN(kIbanValue_0, kNickname_0);
-  SetUpIBAN(kIbanValue_1, kNickname_1);
+  SetUpIBAN(test::kIbanValue, kNickname_0);
+  SetUpIBAN(test::kIbanValue_1, kNickname_1);
   AutofillField test_field;
   // Input a prefix that does not have any matching IBAN value so that no IBAN
   // suggestions will be shown.
diff --git a/components/autofill/core/browser/payments/iban_save_manager_unittest.cc b/components/autofill/core/browser/payments/iban_save_manager_unittest.cc
index bcb1e0b..87a82517 100644
--- a/components/autofill/core/browser/payments/iban_save_manager_unittest.cc
+++ b/components/autofill/core/browser/payments/iban_save_manager_unittest.cc
@@ -19,11 +19,6 @@
 
 namespace autofill {
 
-#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
-constexpr char kIbanValue[] = "DE91 1000 0000 0123 4567 89";
-constexpr char kIbanValueWithoutWhitespaces[] = "DE91100000000123456789";
-#endif  // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
-
 class IBANSaveManagerTest : public testing::Test {
  public:
   IBANSaveManagerTest() {
@@ -67,7 +62,7 @@
 #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
 TEST_F(IBANSaveManagerTest, AttemptToOfferIBANLocalSave_ValidIBAN) {
   IBAN iban(base::GenerateUuid());
-  iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue)));
+  iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue)));
 
   EXPECT_TRUE(GetIBANSaveManager().AttemptToOfferIBANLocalSave(iban));
 }
@@ -75,14 +70,14 @@
 TEST_F(IBANSaveManagerTest, AttemptToOfferIBANLocalSave_IsOffTheRecord) {
   personal_data().set_is_off_the_record_for_testing(true);
   IBAN iban(base::GenerateUuid());
-  iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue)));
+  iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue)));
 
   EXPECT_FALSE(GetIBANSaveManager().AttemptToOfferIBANLocalSave(iban));
 }
 
 TEST_F(IBANSaveManagerTest, OnUserDidDecideOnLocalSave_Accepted) {
   IBAN iban(base::GenerateUuid());
-  iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue)));
+  iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue)));
 
   EXPECT_TRUE(GetIBANSaveManager().AttemptToOfferIBANLocalSave(iban));
 
@@ -95,12 +90,12 @@
   EXPECT_EQ(ibans.size(), 1U);
   EXPECT_EQ(ibans[0]->nickname(), u"My teacher's IBAN");
   EXPECT_EQ(ibans[0]->value(),
-            base::UTF8ToUTF16(std::string(kIbanValueWithoutWhitespaces)));
+            base::UTF8ToUTF16(test::GetStrippedValue(test::kIbanValue)));
 }
 
 TEST_F(IBANSaveManagerTest, OnUserDidDecideOnLocalSave_Declined) {
   IBAN iban(base::GenerateUuid());
-  iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue)));
+  iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue)));
 
   EXPECT_TRUE(iban_save_manager_->AttemptToOfferIBANLocalSave(iban));
   EXPECT_TRUE(personal_data().GetLocalIBANs().empty());
@@ -114,7 +109,7 @@
 
 TEST_F(IBANSaveManagerTest, OnUserDidDecideOnLocalSave_Ignored) {
   IBAN iban(base::GenerateUuid());
-  iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue)));
+  iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue)));
 
   EXPECT_TRUE(iban_save_manager_->AttemptToOfferIBANLocalSave(iban));
   EXPECT_TRUE(personal_data().GetLocalIBANs().empty());
@@ -128,85 +123,86 @@
 
 TEST_F(IBANSaveManagerTest, LocallySaveIBAN_NotEnoughStrikesShouldOfferToSave) {
   IBAN iban(base::GenerateUuid());
-  iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue)));
+  iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue)));
 
   IBANSaveStrikeDatabase iban_save_strike_database(strike_database_);
-  iban_save_strike_database.AddStrike(
-      IBANSaveManager::GetPartialIbanHashString(kIbanValueWithoutWhitespaces));
+  iban_save_strike_database.AddStrike(IBANSaveManager::GetPartialIbanHashString(
+      test::GetStrippedValue(test::kIbanValue)));
 
-  // Verify `kIbanValue` has been successfully added to the strike database.
+  // Verify the IBAN has been successfully added to the strike database.
   EXPECT_EQ(1, iban_save_strike_database.GetStrikes(
                    IBANSaveManager::GetPartialIbanHashString(
-                       kIbanValueWithoutWhitespaces)));
+                       test::GetStrippedValue(test::kIbanValue))));
   EXPECT_TRUE(GetIBANSaveManager().AttemptToOfferIBANLocalSave(iban));
 }
 
 TEST_F(IBANSaveManagerTest, LocallySaveIBAN_MaxStrikesShouldNotOfferToSave) {
   IBAN iban(base::GenerateUuid());
-  iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue)));
+  iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue)));
 
   IBANSaveStrikeDatabase iban_save_strike_database(strike_database_);
   iban_save_strike_database.AddStrikes(
       iban_save_strike_database.GetMaxStrikesLimit(),
-      IBANSaveManager::GetPartialIbanHashString(kIbanValueWithoutWhitespaces));
+      IBANSaveManager::GetPartialIbanHashString(
+          test::GetStrippedValue(test::kIbanValue)));
 
   EXPECT_EQ(iban_save_strike_database.GetMaxStrikesLimit(),
             iban_save_strike_database.GetStrikes(
                 IBANSaveManager::GetPartialIbanHashString(
-                    kIbanValueWithoutWhitespaces)));
+                    test::GetStrippedValue(test::kIbanValue))));
   EXPECT_FALSE(GetIBANSaveManager().AttemptToOfferIBANLocalSave(iban));
 }
 
 TEST_F(IBANSaveManagerTest, OnUserDidDecideOnLocalSave_Accepted_ClearsStrikes) {
   IBAN iban(base::GenerateUuid());
-  iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue)));
+  iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue)));
   EXPECT_TRUE(GetIBANSaveManager().AttemptToOfferIBANLocalSave(iban));
 
   IBANSaveStrikeDatabase iban_save_strike_database(strike_database_);
   iban_save_strike_database.AddStrike(
-      IBANSaveManager::GetPartialIbanHashString(kIbanValueWithoutWhitespaces));
+      IBANSaveManager::GetPartialIbanHashString(test::kIbanValue));
 
-  // Verify partial hashed value of `kIbanValueWithoutWhitespaces` has been
+  // Verify partial hashed value of the IBAN has been
   // successfully added to the strike database.
-  EXPECT_EQ(1, iban_save_strike_database.GetStrikes(
-                   IBANSaveManager::GetPartialIbanHashString(
-                       kIbanValueWithoutWhitespaces)));
+  EXPECT_EQ(1,
+            iban_save_strike_database.GetStrikes(
+                IBANSaveManager::GetPartialIbanHashString(test::kIbanValue)));
   GetIBANSaveManager().OnUserDidDecideOnLocalSaveForTesting(
       AutofillClient::SaveIBANOfferUserDecision::kAccepted,
       u"My teacher's IBAN");
 
-  // Verify partial hashed value of `kIbanValueWithoutWhitespaces` has been
+  // Verify partial hashed value of the IBAN has been
   // cleared in the strike database.
   EXPECT_EQ(0, iban_save_strike_database.GetStrikes(
                    IBANSaveManager::GetPartialIbanHashString(
-                       kIbanValueWithoutWhitespaces)));
+                       test::GetStrippedValue(test::kIbanValue))));
 }
 
 TEST_F(IBANSaveManagerTest, OnUserDidDecideOnLocalSave_Declined_AddsStrike) {
   IBAN iban(base::GenerateUuid());
-  iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue)));
+  iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue)));
   EXPECT_TRUE(GetIBANSaveManager().AttemptToOfferIBANLocalSave(iban));
 
   IBANSaveStrikeDatabase iban_save_strike_database(strike_database_);
 
   EXPECT_EQ(0, iban_save_strike_database.GetStrikes(
                    IBANSaveManager::GetPartialIbanHashString(
-                       kIbanValueWithoutWhitespaces)));
+                       test::GetStrippedValue(test::kIbanValue))));
 
   GetIBANSaveManager().OnUserDidDecideOnLocalSaveForTesting(
       AutofillClient::SaveIBANOfferUserDecision::kDeclined,
       u"My teacher's IBAN");
 
-  // Verify partial hashed value of `kIbanValueWithoutWhitespaces` has been
+  // Verify partial hashed value of the IBAN has been
   // added to the strike database.
   EXPECT_EQ(1, iban_save_strike_database.GetStrikes(
                    IBANSaveManager::GetPartialIbanHashString(
-                       kIbanValueWithoutWhitespaces)));
+                       test::GetStrippedValue(test::kIbanValue))));
 }
 
 TEST_F(IBANSaveManagerTest, OnUserDidDecideOnLocalSave_Ignored_AddsStrike) {
   IBAN iban(base::GenerateUuid());
-  iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue)));
+  iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue)));
 
   EXPECT_TRUE(GetIBANSaveManager().AttemptToOfferIBANLocalSave(iban));
 
@@ -214,22 +210,22 @@
 
   EXPECT_EQ(0, iban_save_strike_database.GetStrikes(
                    IBANSaveManager::GetPartialIbanHashString(
-                       kIbanValueWithoutWhitespaces)));
+                       test::GetStrippedValue(test::kIbanValue))));
 
   GetIBANSaveManager().OnUserDidDecideOnLocalSaveForTesting(
       AutofillClient::SaveIBANOfferUserDecision::kDeclined,
       u"My teacher's IBAN");
 
-  // Verify partial hashed value of `kIbanValueWithoutWhitespaces` has been
+  // Verify partial hashed value of the IBAN has been
   // added to the strike database.
   EXPECT_EQ(1, iban_save_strike_database.GetStrikes(
                    IBANSaveManager::GetPartialIbanHashString(
-                       kIbanValueWithoutWhitespaces)));
+                       test::GetStrippedValue(test::kIbanValue))));
 }
 
 TEST_F(IBANSaveManagerTest, LocallySaveIBAN_AttemptToOfferIBANLocalSave) {
   IBAN iban(base::GenerateUuid());
-  iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue)));
+  iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue)));
 
   EXPECT_TRUE(GetIBANSaveManager().AttemptToOfferIBANLocalSave(iban));
   EXPECT_TRUE(autofill_client_.ConfirmSaveIBANLocallyWasCalled());
@@ -239,16 +235,17 @@
        LocallySaveIBAN_MaxStrikesShouldNotOfferToSave_Metrics) {
   base::HistogramTester histogram_tester;
   IBAN iban(base::GenerateUuid());
-  iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue)));
+  iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue)));
   IBANSaveStrikeDatabase iban_save_strike_database(strike_database_);
   iban_save_strike_database.AddStrikes(
       iban_save_strike_database.GetMaxStrikesLimit(),
-      IBANSaveManager::GetPartialIbanHashString(kIbanValueWithoutWhitespaces));
+      IBANSaveManager::GetPartialIbanHashString(
+          test::GetStrippedValue(test::kIbanValue)));
 
   EXPECT_EQ(iban_save_strike_database.GetMaxStrikesLimit(),
             iban_save_strike_database.GetStrikes(
                 IBANSaveManager::GetPartialIbanHashString(
-                    kIbanValueWithoutWhitespaces)));
+                    test::GetStrippedValue(test::kIbanValue))));
   EXPECT_FALSE(GetIBANSaveManager().AttemptToOfferIBANLocalSave(iban));
   histogram_tester.ExpectBucketCount(
       "Autofill.StrikeDatabase.IbanSaveNotOfferedDueToMaxStrikes",
@@ -258,10 +255,10 @@
 TEST_F(IBANSaveManagerTest, StrikesPresentWhenIBANSaved_Local) {
   base::HistogramTester histogram_tester;
   IBAN iban(base::GenerateUuid());
-  iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue)));
+  iban.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue)));
   IBANSaveStrikeDatabase iban_save_strike_database(strike_database_);
-  iban_save_strike_database.AddStrike(
-      IBANSaveManager::GetPartialIbanHashString(kIbanValueWithoutWhitespaces));
+  iban_save_strike_database.AddStrike(IBANSaveManager::GetPartialIbanHashString(
+      test::GetStrippedValue(test::kIbanValue)));
 
   EXPECT_TRUE(GetIBANSaveManager().AttemptToOfferIBANLocalSave(iban));
   GetIBANSaveManager().OnUserDidDecideOnLocalSaveForTesting(
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc
index 5988c219c..1299a97f 100644
--- a/components/autofill/core/browser/personal_data_manager_unittest.cc
+++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -906,11 +906,11 @@
 TEST_F(PersonalDataManagerTest, NoIBANsAddedIfDisabled) {
   prefs::SetAutofillIBANEnabled(prefs_.get(), false);
   IBAN iban0(base::GenerateUuid());
-  iban0.set_value(u"IE12 BOFI 9000 0112 3456 78");
+  iban0.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue)));
   iban0.set_nickname(u"Nickname 0");
 
   IBAN iban1(base::GenerateUuid());
-  iban1.set_value(u"DE91 1000 0000 0123 4567 89");
+  iban0.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue_1)));
   iban1.set_nickname(u"Nickname 1");
 
   personal_data_->AddIBAN(iban0);
@@ -934,18 +934,18 @@
 TEST_F(PersonalDataManagerTest, AddUpdateRemoveIBANs) {
   prefs::SetAutofillIBANEnabled(prefs_.get(), true);
   IBAN iban0(base::GenerateUuid());
-  iban0.set_value(u"IE12 BOFI 9000 0112 3456 78");
+  iban0.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue)));
   iban0.set_nickname(u"Nickname 0");
 
   IBAN iban1(base::GenerateUuid());
-  iban1.set_value(u"DE91 1000 0000 0123 4567 89");
+  iban0.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue_1)));
   iban1.set_nickname(u"Nickname 1");
 
   IBAN iban1_1 = iban1;
   iban1_1.set_nickname(u"Nickname 1_1");
 
   IBAN iban2(base::GenerateUuid());
-  iban2.set_value(u"ES79 2100 0813 6101 2345 6789");
+  iban0.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue_2)));
   iban2.set_nickname(u"Nickname 2");
 
   // Add two test IBANs to the database. `iban1_1` has the same value
@@ -1010,7 +1010,7 @@
 
   // Start with a new IBAN.
   IBAN iban0(base::GenerateUuid());
-  iban0.set_value(u"FR76 3000 6000 0112 3456 7890 189");
+  iban0.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue)));
   iban0.set_nickname(u"Nickname 0");
   // Add the IBAN to the database.
   personal_data_->OnAcceptedLocalIBANSave(iban0);
@@ -1022,7 +1022,7 @@
   // Creates a new IBAN and call `OnAcceptedLocalIBANSave()` and verify that
   // the new IBAN is saved.
   IBAN iban1(base::GenerateUuid());
-  iban1.set_value(u"DE91 1000 0000 0123 4567 89");
+  iban1.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue_1)));
   iban1.set_nickname(u"Nickname 1");
   personal_data_->OnAcceptedLocalIBANSave(iban1);
   WaitForOnPersonalDataChanged();
@@ -1039,7 +1039,7 @@
   // Creates a new `iban2` which has the same value as `iban0` but with
   // different nickname and call `OnAcceptedLocalIBANSave()`.
   IBAN iban2(base::GenerateUuid());
-  iban2.set_value(u"FR76 3000 6000 0112 3456 7890 189");
+  iban2.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue)));
   iban2.set_nickname(u"Nickname 2");
   personal_data_->OnAcceptedLocalIBANSave(iban2);
   WaitForOnPersonalDataChanged();
@@ -1077,7 +1077,7 @@
 
   // Start with a new IBAN.
   IBAN iban0(base::GenerateUuid());
-  iban0.set_value(u"FR76 3000 6000 0112 3456 7890 189");
+  iban0.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue)));
   iban0.set_nickname(u"Nickname 0");
 
   // Add the IBAN to the database.
@@ -1089,7 +1089,7 @@
   // Creates a new IBAN and call `OnAcceptedLocalIBANSave()` and verify that
   // the new IBAN is not saved.
   IBAN iban1(base::GenerateUuid());
-  iban1.set_value(u"DE91 1000 0000 0123 4567 89");
+  iban1.set_value(base::UTF8ToUTF16(std::string(test::kIbanValue_1)));
   iban1.set_nickname(u"Nickname 1");
   personal_data_->OnAcceptedLocalIBANSave(iban1);
 
diff --git a/components/autofill_strings.grdp b/components/autofill_strings.grdp
index fb4e030..5b587dc 100644
--- a/components/autofill_strings.grdp
+++ b/components/autofill_strings.grdp
@@ -235,6 +235,9 @@
   <message name="IDS_AUTOFILL_ADDRESS_WILL_BE_SAVED_IN_ACCOUNT_SOURCE_NOTICE" desc="The footer message used to notify user that their address will be saved in their account." formatter_data="android_java">
     You can use saved addresses across Google products. This address will be saved in your Google Account (<ph name="ACCOUNT">$1<ex>alexpark@gmail.com</ex></ph>).
   </message>
+  <message name="IDS_AUTOFILL_ADDRESS_WILL_BE_MIGRATED_TO_ACCOUNT_SOURCE_NOTICE" desc="The description message used to notify the user that their address will be migrated to their account." formatter_data="android_java">
+    This address is saved only to Chrome. To use it across Google products, save it in your Google Account, (<ph name="ACCOUNT">$1<ex>alexpark@gmail.com</ex></ph>).
+  </message>
   <message name="IDS_AUTOFILL_EDIT_ADDRESS_REQUIRED_FIELD_FORM_ERROR" desc="The form error message shown to the user in case of a single required field missing.">
     A required field is empty. Fill it before saving.
   </message>
diff --git a/components/autofill_strings_grdp/IDS_AUTOFILL_ADDRESS_WILL_BE_MIGRATED_TO_ACCOUNT_SOURCE_NOTICE.png.sha1 b/components/autofill_strings_grdp/IDS_AUTOFILL_ADDRESS_WILL_BE_MIGRATED_TO_ACCOUNT_SOURCE_NOTICE.png.sha1
new file mode 100644
index 0000000..3eda7da
--- /dev/null
+++ b/components/autofill_strings_grdp/IDS_AUTOFILL_ADDRESS_WILL_BE_MIGRATED_TO_ACCOUNT_SOURCE_NOTICE.png.sha1
@@ -0,0 +1 @@
+bc1f614b455da4273811dc7777fc293ad6bffbad
\ No newline at end of file
diff --git a/components/browser_ui/bottomsheet/android/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheet.java b/components/browser_ui/bottomsheet/android/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheet.java
index 0488a86..6f3addd 100644
--- a/components/browser_ui/bottomsheet/android/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheet.java
+++ b/components/browser_ui/bottomsheet/android/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheet.java
@@ -923,7 +923,8 @@
         // Setting state to SCROLLING is not a valid operation. This can happen only when
         // we're already in the scrolling state. Make it no-op.
         if (state == SheetState.SCROLLING) {
-            assert mCurrentState == SheetState.SCROLLING && isRunningSettleAnimation();
+            // TODO(mdjones): The isRunningSettleAnimation should hold but currently doesn't.
+            assert mCurrentState == SheetState.SCROLLING; // && isRunningSettleAnimation();
             return;
         }
 
diff --git a/components/browser_ui/bottomsheet/android/test/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetTestSupport.java b/components/browser_ui/bottomsheet/android/test/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetTestSupport.java
index e88f45d..57dc887 100644
--- a/components/browser_ui/bottomsheet/android/test/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetTestSupport.java
+++ b/components/browser_ui/bottomsheet/android/test/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetTestSupport.java
@@ -4,6 +4,7 @@
 
 package org.chromium.components.browser_ui.bottomsheet;
 
+import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.SheetState;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.StateChangeReason;
@@ -112,7 +113,8 @@
      * @return Whether has any token to suppress the bottom sheet.
      */
     public boolean hasSuppressionTokens() {
-        return mController.hasSuppressionTokensForTesting();
+        return ThreadUtils.runOnUiThreadBlockingNoException(
+                () -> mController.hasSuppressionTokensForTesting());
     }
 
     /**
diff --git a/components/feature_engagement/public/feature_configurations.cc b/components/feature_engagement/public/feature_configurations.cc
index 96f576a..07c252b 100644
--- a/components/feature_engagement/public/feature_configurations.cc
+++ b/components/feature_engagement/public/feature_configurations.cc
@@ -162,20 +162,6 @@
     return config;
   }
 
-  if (kIPHHighEfficiencyInfoModeFeature.name == feature->name) {
-    absl::optional<FeatureConfig> config = FeatureConfig();
-    config->valid = true;
-    config->availability = Comparator(ANY, 0);
-    config->session_rate = Comparator(EQUAL, 0);
-    // Show the promo up to 3 times if the page action chip was not opened
-    // within the last week
-    config->trigger = EventConfig("high_efficiency_info_trigger",
-                                  Comparator(LESS_THAN, 3), 360, 360);
-    config->used =
-        EventConfig("high_efficiency_info_shown", Comparator(EQUAL, 0), 7, 360);
-    return config;
-  }
-
   if (kIPHHighEfficiencyModeFeature.name == feature->name) {
     absl::optional<FeatureConfig> config = FeatureConfig();
     config->valid = true;
diff --git a/components/feature_engagement/public/feature_constants.cc b/components/feature_engagement/public/feature_constants.cc
index de71e7d1..a9aab07 100644
--- a/components/feature_engagement/public/feature_constants.cc
+++ b/components/feature_engagement/public/feature_constants.cc
@@ -44,9 +44,6 @@
 BASE_FEATURE(kIPHGMCCastStartStopFeature,
              "IPH_GMCCastStartStop",
              base::FEATURE_ENABLED_BY_DEFAULT);
-BASE_FEATURE(kIPHHighEfficiencyInfoModeFeature,
-             "IPH_HighEfficiencyInfoMode",
-             base::FEATURE_DISABLED_BY_DEFAULT);
 BASE_FEATURE(kIPHHighEfficiencyModeFeature,
              "IPH_HighEfficiencyMode",
              base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/components/feature_engagement/public/feature_constants.h b/components/feature_engagement/public/feature_constants.h
index a5824b8..1bad8ab5f 100644
--- a/components/feature_engagement/public/feature_constants.h
+++ b/components/feature_engagement/public/feature_constants.h
@@ -31,7 +31,6 @@
 BASE_DECLARE_FEATURE(kIPHExtensionsMenuFeature);
 BASE_DECLARE_FEATURE(kIPHFocusHelpBubbleScreenReaderPromoFeature);
 BASE_DECLARE_FEATURE(kIPHGMCCastStartStopFeature);
-BASE_DECLARE_FEATURE(kIPHHighEfficiencyInfoModeFeature);
 BASE_DECLARE_FEATURE(kIPHHighEfficiencyModeFeature);
 BASE_DECLARE_FEATURE(kIPHLiveCaptionFeature);
 BASE_DECLARE_FEATURE(kIPHTabAudioMutingFeature);
diff --git a/components/feature_engagement/public/feature_list.cc b/components/feature_engagement/public/feature_list.cc
index bf9c3bd7..b428e41 100644
--- a/components/feature_engagement/public/feature_list.cc
+++ b/components/feature_engagement/public/feature_list.cc
@@ -142,7 +142,6 @@
     &kIPHExtensionsMenuFeature,
     &kIPHFocusHelpBubbleScreenReaderPromoFeature,
     &kIPHGMCCastStartStopFeature,
-    &kIPHHighEfficiencyInfoModeFeature,
     &kIPHHighEfficiencyModeFeature,
     &kIPHLiveCaptionFeature,
     &kIPHTabAudioMutingFeature,
diff --git a/components/feature_engagement/public/feature_list.h b/components/feature_engagement/public/feature_list.h
index a972135d..d38335ab 100644
--- a/components/feature_engagement/public/feature_list.h
+++ b/components/feature_engagement/public/feature_list.h
@@ -258,8 +258,6 @@
 DEFINE_VARIATION_PARAM(kIPHFocusModeFeature, "IPH_FocusMode");
 DEFINE_VARIATION_PARAM(kIPHGlobalMediaControls, "IPH_GlobalMediaControls");
 DEFINE_VARIATION_PARAM(kIPHGMCCastStartStopFeature, "IPH_GMCCastStartStop");
-DEFINE_VARIATION_PARAM(kIPHHighEfficiencyInfoModeFeature,
-                       "IPH_HighEfficiencyInfoMode");
 DEFINE_VARIATION_PARAM(kIPHHighEfficiencyModeFeature, "IPH_HighEfficiencyMode");
 DEFINE_VARIATION_PARAM(kIPHLiveCaption, "IPH_LiveCaption");
 DEFINE_VARIATION_PARAM(kIPHPasswordsAccountStorageFeature,
@@ -442,7 +440,6 @@
         VARIATION_ENTRY(kIPHFocusModeFeature),
         VARIATION_ENTRY(kIPHGlobalMediaControls),
         VARIATION_ENTRY(kIPHGMCCastStartStopFeature),
-        VARIATION_ENTRY(kIPHHighEfficiencyInfoModeFeature),
         VARIATION_ENTRY(kIPHHighEfficiencyModeFeature),
         VARIATION_ENTRY(kIPHLiveCaption),
         VARIATION_ENTRY(kIPHPasswordsAccountStorageFeature),
diff --git a/components/media_router/browser/mirroring_media_controller_host.cc b/components/media_router/browser/mirroring_media_controller_host.cc
index 29a5eac..0300cbf 100644
--- a/components/media_router/browser/mirroring_media_controller_host.cc
+++ b/components/media_router/browser/mirroring_media_controller_host.cc
@@ -35,11 +35,17 @@
   observers_.RemoveObserver(observer);
 }
 
-// TODO(b/271442872): Update these two method once freeze and unfreeze are
-// implemented in MediaController.
-void MirroringMediaControllerHost::Freeze() {}
+void MirroringMediaControllerHost::Freeze() {
+  if (mirroring_controller_) {
+    mirroring_controller_->Pause();
+  }
+}
 
-void MirroringMediaControllerHost::Unfreeze() {}
+void MirroringMediaControllerHost::Unfreeze() {
+  if (mirroring_controller_) {
+    mirroring_controller_->Play();
+  }
+}
 
 void MirroringMediaControllerHost::OnMediaStatusUpdated(
     media_router::mojom::MediaStatusPtr status) {
diff --git a/components/media_router/browser/mirroring_media_controller_host_unittest.cc b/components/media_router/browser/mirroring_media_controller_host_unittest.cc
index d9c7dac..13abb56 100644
--- a/components/media_router/browser/mirroring_media_controller_host_unittest.cc
+++ b/components/media_router/browser/mirroring_media_controller_host_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "components/media_router/browser/mirroring_media_controller_host.h"
 
+#include "base/run_loop.h"
+#include "base/test/gmock_callback_support.h"
 #include "base/test/task_environment.h"
 #include "components/media_router/common/media_route.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -33,20 +35,45 @@
   raw_ptr<MirroringMediaControllerHost> host_ = nullptr;
 };
 
+class MockMediaController : public mojom::MediaController {
+ public:
+  explicit MockMediaController(
+      mojo::PendingReceiver<mojom::MediaController> receiver)
+      : receiver_(this, std::move(receiver)) {}
+  ~MockMediaController() override = default;
+
+  MOCK_METHOD(void, Play, ());
+  MOCK_METHOD(void, Pause, ());
+  MOCK_METHOD(void, SetMute, (bool mute));
+  MOCK_METHOD(void, SetVolume, (float volume));
+  MOCK_METHOD(void, Seek, (base::TimeDelta time));
+  MOCK_METHOD(void, NextTrack, ());
+  MOCK_METHOD(void, PreviousTrack, ());
+
+  void FlushForTesting() { receiver_.FlushForTesting(); }
+
+ private:
+  mojo::Receiver<mojom::MediaController> receiver_;
+};
+
 class MirroringMediaControllerHostTest : public ::testing::Test {
  public:
   MirroringMediaControllerHostTest() = default;
   ~MirroringMediaControllerHostTest() override = default;
 
   void SetUp() override {
+    mojo::Remote<mojom::MediaController> controller_remote;
+    media_controller_ = std::make_unique<MockMediaController>(
+        controller_remote.BindNewPipeAndPassReceiver());
+
     host_ = std::make_unique<MirroringMediaControllerHost>(
-        std::move(controller_remote_));
+        std::move(controller_remote));
   }
 
  protected:
   base::test::SingleThreadTaskEnvironment task_environment_;
-  mojo::Remote<mojom::MediaController> controller_remote_;
   std::unique_ptr<MirroringMediaControllerHost> host_;
+  std::unique_ptr<MockMediaController> media_controller_;
 };
 
 TEST_F(MirroringMediaControllerHostTest, GetMediaStatusObserverPendingRemote) {
@@ -62,4 +89,16 @@
   host_->OnMediaStatusUpdated({});
 }
 
+TEST_F(MirroringMediaControllerHostTest, Freeze) {
+  EXPECT_CALL(*media_controller_, Pause);
+  host_->Freeze();
+  media_controller_->FlushForTesting();
+}
+
+TEST_F(MirroringMediaControllerHostTest, Unfreeze) {
+  EXPECT_CALL(*media_controller_, Play);
+  host_->Unfreeze();
+  media_controller_->FlushForTesting();
+}
+
 }  // namespace media_router
diff --git a/components/omnibox/browser/BUILD.gn b/components/omnibox/browser/BUILD.gn
index 7dcede2..b248bd3e 100644
--- a/components/omnibox/browser/BUILD.gn
+++ b/components/omnibox/browser/BUILD.gn
@@ -38,6 +38,8 @@
     "chevron.icon",
     "clear.icon",
     "clock.icon",
+    "cookie_chrome_refresh.icon",
+    "cookie_crossed_chrome_refresh.icon",
     "dino.icon",
     "drive_docs.icon",
     "drive_folder.icon",
@@ -50,6 +52,7 @@
     "drive_video.icon",
     "extension_app.icon",
     "find_in_page.icon",
+    "find_in_page_chrome_refresh.icon",
     "http.icon",
     "http_chrome_refresh.icon",
     "https_valid_in_chip.icon",
diff --git a/components/omnibox/browser/vector_icons/cookie_chrome_refresh.icon b/components/omnibox/browser/vector_icons/cookie_chrome_refresh.icon
new file mode 100644
index 0000000..10b6235b
--- /dev/null
+++ b/components/omnibox/browser/vector_icons/cookie_chrome_refresh.icon
@@ -0,0 +1,68 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+CANVAS_DIMENSIONS, 20,
+MOVE_TO, 8.75f, 8.5f,
+R_CUBIC_TO, 0.35f, 0, 0.64f, -0.12f, 0.89f, -0.36f,
+R_CUBIC_TO, 0.25f, -0.24f, 0.36f, -0.54f, 0.36f, -0.89f,
+R_CUBIC_TO, 0, -0.35f, -0.12f, -0.64f, -0.36f, -0.89f,
+CUBIC_TO_SHORTHAND, 9.1f, 6, 8.75f, 6,
+R_CUBIC_TO, -0.35f, 0, -0.64f, 0.12f, -0.89f, 0.36f,
+R_CUBIC_TO, -0.25f, 0.24f, -0.36f, 0.54f, -0.36f, 0.89f,
+R_CUBIC_TO, 0, 0.35f, 0.12f, 0.64f, 0.36f, 0.89f,
+R_CUBIC_TO, 0.24f, 0.25f, 0.54f, 0.36f, 0.89f, 0.36f,
+CLOSE,
+R_MOVE_TO, -2, 4,
+R_CUBIC_TO, 0.35f, 0, 0.64f, -0.12f, 0.89f, -0.36f,
+R_CUBIC_TO, 0.25f, -0.24f, 0.36f, -0.54f, 0.36f, -0.89f,
+R_CUBIC_TO, 0, -0.35f, -0.12f, -0.64f, -0.36f, -0.89f,
+CUBIC_TO_SHORTHAND, 7.1f, 10, 6.75f, 10,
+R_CUBIC_TO, -0.35f, 0, -0.64f, 0.12f, -0.89f, 0.36f,
+R_CUBIC_TO, -0.25f, 0.24f, -0.36f, 0.54f, -0.36f, 0.89f,
+R_CUBIC_TO, 0, 0.35f, 0.12f, 0.64f, 0.36f, 0.89f,
+R_CUBIC_TO, 0.24f, 0.25f, 0.54f, 0.36f, 0.89f, 0.36f,
+CLOSE,
+R_MOVE_TO, 5.75f, 0.75f,
+R_CUBIC_TO, 0.21f, 0, 0.39f, -0.07f, 0.54f, -0.21f,
+R_CUBIC_TO, 0.15f, -0.14f, 0.22f, -0.32f, 0.22f, -0.53f,
+R_CUBIC_TO, 0, -0.21f, -0.07f, -0.39f, -0.21f, -0.54f,
+R_CUBIC_TO, -0.14f, -0.15f, -0.32f, -0.22f, -0.53f, -0.22f,
+R_CUBIC_TO, -0.21f, 0, -0.39f, 0.07f, -0.54f, 0.21f,
+R_CUBIC_TO, -0.15f, 0.14f, -0.22f, 0.32f, -0.22f, 0.53f,
+R_CUBIC_TO, 0, 0.21f, 0.07f, 0.39f, 0.21f, 0.54f,
+R_CUBIC_TO, 0.14f, 0.15f, 0.32f, 0.22f, 0.53f, 0.22f,
+CLOSE,
+MOVE_TO, 10, 18,
+R_CUBIC_TO, -1.1f, 0, -2.14f, -0.21f, -3.11f, -0.63f,
+R_CUBIC_TO, -0.97f, -0.42f, -1.82f, -0.99f, -2.55f, -1.72f,
+R_CUBIC_TO, -0.73f, -0.73f, -1.3f, -1.58f, -1.72f, -2.55f,
+R_CUBIC_TO, -0.42f, -0.97f, -0.63f, -2.01f, -0.63f, -3.11f,
+R_CUBIC_TO, 0, -1.29f, 0.28f, -2.49f, 0.84f, -3.59f,
+R_CUBIC_TO, 0.56f, -1.1f, 1.3f, -2.02f, 2.22f, -2.76f,
+CUBIC_TO, 5.97f, 2.9f, 7, 2.39f, 8.15f, 2.1f,
+R_CUBIC_TO, 1.15f, -0.29f, 2.32f, -0.27f, 3.5f, 0.06f,
+R_CUBIC_TO, -0.11f, 0.61f, -0.08f, 1.17f, 0.1f, 1.69f,
+R_CUBIC_TO, 0.18f, 0.52f, 0.47f, 0.94f, 0.85f, 1.28f,
+R_CUBIC_TO, 0.38f, 0.34f, 0.86f, 0.58f, 1.42f, 0.71f,
+R_CUBIC_TO, 0.56f, 0.13f, 1.15f, 0.12f, 1.77f, -0.03f,
+R_CUBIC_TO, -0.35f, 0.79f, -0.3f, 1.55f, 0.16f, 2.26f,
+R_CUBIC_TO, 0.45f, 0.72f, 1.11f, 1.09f, 1.99f, 1.11f,
+R_CUBIC_TO, 0.13f, 1.18f, 0, 2.3f, -0.38f, 3.37f,
+R_CUBIC_TO, -0.38f, 1.06f, -0.93f, 2, -1.65f, 2.8f,
+R_CUBIC_TO, -0.73f, 0.81f, -1.6f, 1.45f, -2.62f, 1.93f,
+R_CUBIC_TO, -1.02f, 0.48f, -2.12f, 0.72f, -3.31f, 0.72f,
+CLOSE,
+R_MOVE_TO, 0, -1.5f,
+R_CUBIC_TO, 1.74f, 0, 3.23f, -0.59f, 4.47f, -1.76f,
+R_CUBIC_TO, 1.24f, -1.17f, 1.92f, -2.63f, 2.03f, -4.36f,
+R_CUBIC_TO, -0.63f, -0.25f, -1.15f, -0.64f, -1.56f, -1.16f,
+R_CUBIC_TO, -0.41f, -0.52f, -0.68f, -1.11f, -0.79f, -1.78f,
+R_CUBIC_TO, -1.06f, -0.15f, -1.95f, -0.59f, -2.69f, -1.31f,
+R_CUBIC_TO, -0.74f, -0.72f, -1.17f, -1.6f, -1.31f, -2.63f,
+R_CUBIC_TO, -0.88f, -0.06f, -1.71f, 0.08f, -2.51f, 0.41f,
+R_ARC_TO, 6.71f, 6.71f, 0, 0, 0, -3.6f, 3.5f,
+R_CUBIC_TO, -0.36f, 0.81f, -0.54f, 1.68f, -0.54f, 2.59f,
+R_CUBIC_TO, 0, 1.8f, 0.63f, 3.33f, 1.9f, 4.6f,
+R_CUBIC_TO, 1.27f, 1.27f, 2.8f, 1.9f, 4.6f, 1.9f,
+CLOSE
diff --git a/components/omnibox/browser/vector_icons/cookie_crossed_chrome_refresh.icon b/components/omnibox/browser/vector_icons/cookie_crossed_chrome_refresh.icon
new file mode 100644
index 0000000..3819f684
--- /dev/null
+++ b/components/omnibox/browser/vector_icons/cookie_crossed_chrome_refresh.icon
@@ -0,0 +1,61 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+CANVAS_DIMENSIONS, 20,
+R_MOVE_TO, 16.63f, 14.5f,
+R_LINE_TO, -1.1f, -1.1f,
+R_CUBIC_TO, 0.28f, -0.44f, 0.5f, -0.92f, 0.66f, -1.43f,
+R_CUBIC_TO, 0.17f, -0.51f, 0.27f, -1.04f, 0.31f, -1.59f,
+R_CUBIC_TO, -0.63f, -0.25f, -1.15f, -0.64f, -1.56f, -1.16f,
+R_CUBIC_TO, -0.41f, -0.52f, -0.68f, -1.11f, -0.79f, -1.78f,
+R_CUBIC_TO, -1.06f, -0.15f, -1.95f, -0.59f, -2.69f, -1.31f,
+R_CUBIC_TO, -0.74f, -0.72f, -1.17f, -1.6f, -1.31f, -2.63f,
+R_CUBIC_TO, -0.65f, -0.04f, -1.28f, 0.02f, -1.89f, 0.19f,
+R_CUBIC_TO, -0.61f, 0.17f, -1.17f, 0.42f, -1.7f, 0.75f,
+R_LINE_TO, -1.1f, -1.1f,
+R_CUBIC_TO, 0.89f, -0.64f, 1.87f, -1.07f, 2.95f, -1.3f,
+R_CUBIC_TO, 1.08f, -0.23f, 2.16f, -0.18f, 3.26f, 0.14f,
+R_CUBIC_TO, -0.11f, 0.61f, -0.08f, 1.17f, 0.1f, 1.69f,
+R_CUBIC_TO, 0.18f, 0.52f, 0.47f, 0.94f, 0.85f, 1.28f,
+R_CUBIC_TO, 0.38f, 0.34f, 0.86f, 0.58f, 1.42f, 0.71f,
+R_CUBIC_TO, 0.56f, 0.13f, 1.15f, 0.12f, 1.77f, -0.03f,
+R_CUBIC_TO, -0.35f, 0.79f, -0.3f, 1.55f, 0.16f, 2.26f,
+R_CUBIC_TO, 0.45f, 0.72f, 1.11f, 1.09f, 1.99f, 1.11f,
+R_CUBIC_TO, 0.11f, 0.99f, 0.05f, 1.93f, -0.2f, 2.83f,
+R_CUBIC_TO, -0.24f, 0.9f, -0.62f, 1.73f, -1.14f, 2.48f,
+CLOSE,
+R_MOVE_TO, -9.88f, -2,
+R_CUBIC_TO, -0.35f, 0, -0.64f, -0.12f, -0.89f, -0.36f,
+R_CUBIC_TO, -0.25f, -0.24f, -0.36f, -0.54f, -0.36f, -0.89f,
+R_CUBIC_TO, 0, -0.35f, 0.12f, -0.64f, 0.36f, -0.89f,
+R_CUBIC_TO, 0.24f, -0.25f, 0.54f, -0.36f, 0.89f, -0.36f,
+R_CUBIC_TO, 0.35f, 0, 0.64f, 0.12f, 0.89f, 0.36f,
+R_CUBIC_TO, 0.25f, 0.24f, 0.36f, 0.54f, 0.36f, 0.89f,
+R_CUBIC_TO, 0, 0.35f, -0.12f, 0.64f, -0.36f, 0.89f,
+R_CUBIC_TO, -0.24f, 0.25f, -0.54f, 0.36f, -0.89f, 0.36f,
+CLOSE,
+MOVE_TO, 16, 18.13f,
+R_LINE_TO, -1.5f, -1.5f,
+R_CUBIC_TO, -0.68f, 0.44f, -1.4f, 0.78f, -2.16f, 1.02f,
+CUBIC_TO_SHORTHAND, 10.8f, 18, 10, 18,
+R_CUBIC_TO, -1.1f, 0, -2.14f, -0.21f, -3.11f, -0.63f,
+R_CUBIC_TO, -0.97f, -0.42f, -1.82f, -0.99f, -2.55f, -1.72f,
+R_CUBIC_TO, -0.73f, -0.73f, -1.3f, -1.58f, -1.72f, -2.55f,
+R_CUBIC_TO, -0.42f, -0.97f, -0.63f, -2.01f, -0.63f, -3.11f,
+R_CUBIC_TO, 0, -0.81f, 0.12f, -1.59f, 0.35f, -2.34f,
+R_CUBIC_TO, 0.23f, -0.75f, 0.58f, -1.48f, 1.02f, -2.16f,
+R_LINE_TO, -1.5f, -1.5f,
+R_LINE_TO, 1.06f, -1.06f,
+R_LINE_TO, 14.13f, 14.13f,
+R_LINE_TO, -1.06f, 1.06f,
+CLOSE,
+R_MOVE_TO, -6, -1.63f,
+R_CUBIC_TO, 0.61f, 0, 1.2f, -0.09f, 1.77f, -0.27f,
+R_CUBIC_TO, 0.57f, -0.18f, 1.12f, -0.42f, 1.65f, -0.71f,
+LINE_TO, 4.48f, 6.58f,
+R_CUBIC_TO, -0.29f, 0.53f, -0.53f, 1.08f, -0.71f, 1.65f,
+R_CUBIC_TO, -0.18f, 0.57f, -0.27f, 1.16f, -0.27f, 1.77f,
+R_CUBIC_TO, 0, 1.8f, 0.63f, 3.34f, 1.9f, 4.6f,
+R_CUBIC_TO, 1.27f, 1.27f, 2.8f, 1.9f, 4.6f, 1.9f,
+CLOSE
diff --git a/components/omnibox/browser/vector_icons/find_in_page_chrome_refresh.icon b/components/omnibox/browser/vector_icons/find_in_page_chrome_refresh.icon
new file mode 100644
index 0000000..5904b2b
--- /dev/null
+++ b/components/omnibox/browser/vector_icons/find_in_page_chrome_refresh.icon
@@ -0,0 +1,46 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+CANVAS_DIMENSIONS, 20,
+R_MOVE_TO, 12.33f, 16.5f,
+R_LINE_TO, 1.5f, 1.5f,
+H_LINE_TO, 5.5f,
+R_CUBIC_TO, -0.41f, 0, -0.77f, -0.15f, -1.06f, -0.44f,
+R_CUBIC_TO, -0.29f, -0.29f, -0.44f, -0.65f, -0.44f, -1.06f,
+R_V_LINE_TO, -13,
+R_CUBIC_TO, 0, -0.41f, 0.15f, -0.77f, 0.44f, -1.06f,
+R_CUBIC_TO, 0.29f, -0.29f, 0.65f, -0.44f, 1.06f, -0.44f,
+H_LINE_TO, 12,
+R_LINE_TO, 4, 4,
+R_V_LINE_TO, 9.92f,
+R_CUBIC_TO, 0, 0.5f, -0.04f, 0.88f, -0.11f, 1.13f,
+R_CUBIC_TO, -0.07f, 0.25f, -0.19f, 0.43f, -0.34f, 0.54f,
+R_LINE_TO, -4.02f, -4.02f,
+R_CUBIC_TO, -0.21f, 0.14f, -0.44f, 0.24f, -0.71f, 0.3f,
+R_CUBIC_TO, -0.26f, 0.06f, -0.53f, 0.09f, -0.81f, 0.09f,
+R_CUBIC_TO, -0.83f, 0, -1.54f, -0.29f, -2.13f, -0.88f,
+CUBIC_TO_SHORTHAND, 7, 11.79f, 7, 10.95f,
+R_CUBIC_TO, 0, -0.84f, 0.29f, -1.54f, 0.88f, -2.13f,
+R_CUBIC_TO, 0.59f, -0.59f, 1.29f, -0.88f, 2.13f, -0.88f,
+R_CUBIC_TO, 0.84f, 0, 1.54f, 0.29f, 2.13f, 0.88f,
+R_CUBIC_TO, 0.59f, 0.59f, 0.88f, 1.29f, 0.88f, 2.13f,
+R_CUBIC_TO, 0, 0.28f, -0.03f, 0.55f, -0.1f, 0.82f,
+R_CUBIC_TO, -0.07f, 0.27f, -0.17f, 0.51f, -0.31f, 0.72f,
+R_LINE_TO, 1.92f, 1.92f,
+V_LINE_TO, 6.63f,
+LINE_TO, 11.4f, 3.5f,
+H_LINE_TO, 5.5f,
+R_V_LINE_TO, 13,
+R_H_LINE_TO, 6.83f,
+CLOSE,
+MOVE_TO, 10, 12.46f,
+R_CUBIC_TO, 0.41f, 0, 0.77f, -0.15f, 1.06f, -0.46f,
+R_CUBIC_TO, 0.29f, -0.31f, 0.44f, -0.72f, 0.44f, -1.25f,
+R_CUBIC_TO, 0, -0.32f, -0.15f, -0.61f, -0.44f, -0.89f,
+R_CUBIC_TO, -0.29f, -0.27f, -0.65f, -0.41f, -1.06f, -0.41f,
+R_CUBIC_TO, -0.41f, 0, -0.77f, 0.14f, -1.06f, 0.41f,
+R_CUBIC_TO, -0.29f, 0.27f, -0.44f, 0.57f, -0.44f, 0.89f,
+R_CUBIC_TO, 0, 0.53f, 0.15f, 0.94f, 0.44f, 1.25f,
+R_CUBIC_TO, 0.29f, 0.31f, 0.65f, 0.46f, 1.06f, 0.46f,
+CLOSE
diff --git a/components/omnibox/browser/vector_icons/secure_page_info_chrome_refresh.icon b/components/omnibox/browser/vector_icons/secure_page_info_chrome_refresh.icon
index a0e65d49..71dbfaf 100644
--- a/components/omnibox/browser/vector_icons/secure_page_info_chrome_refresh.icon
+++ b/components/omnibox/browser/vector_icons/secure_page_info_chrome_refresh.icon
@@ -3,33 +3,35 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 4.25f, 7,
-CUBIC_TO, 5.49f, 7, 6.5f, 5.99f, 6.5f, 4.75f,
-CUBIC_TO_SHORTHAND, 5.49f, 2.5f, 4.25f, 2.5f,
-CUBIC_TO_SHORTHAND, 2, 3.51f, 2, 4.75f,
-CUBIC_TO_SHORTHAND, 3.01f, 7, 4.25f, 7,
-CLOSE,
-R_MOVE_TO, 0, -3.1f,
-R_ARC_TO, 0.85f, 0.85f, 0, 1, 1, 0, 1.7f,
-ARC_TO, 0.85f, 0.85f, 0, 0, 1, 4.25f, 3.9f,
-CLOSE,
-MOVE_TO, 8, 4,
-R_H_LINE_TO, 6,
+MOVE_TO, 14, 5.75f,
+R_V_LINE_TO, -1.5f,
+H_LINE_TO, 8.5f,
 R_V_LINE_TO, 1.5f,
-H_LINE_TO, 8,
+H_LINE_TO, 14,
 CLOSE,
-MOVE_TO, 11.75f, 9,
-R_CUBIC_TO, -1.24f, 0, -2.25f, 1.01f, -2.25f, 2.25f,
-R_CUBIC_TO, 0, 1.24f, 1.01f, 2.25f, 2.25f, 2.25f,
-CUBIC_TO_SHORTHAND, 14, 12.49f, 14, 11.25f,
-CUBIC_TO_SHORTHAND, 12.99f, 9, 11.75f, 9,
-CLOSE,
-R_MOVE_TO, 0, 3.1f,
-R_ARC_TO, 0.85f, 0.85f, 0, 1, 1, 0, -1.7f,
-R_ARC_TO, 0.85f, 0.85f, 0, 0, 1, 0, 1.7f,
-CLOSE,
-MOVE_TO, 2, 10.5f,
-R_H_LINE_TO, 6,
-V_LINE_TO, 12,
+R_MOVE_TO, -12, 4.5f,
+R_V_LINE_TO, 1.5f,
+R_H_LINE_TO, 5.5f,
+R_V_LINE_TO, -1.5f,
 H_LINE_TO, 2,
-CLOSE
+CLOSE,
+MOVE_TO, 4.5f, 4,
+R_CUBIC_TO, 0.55f, 0, 1, 0.45f, 1, 1,
+R_CUBIC_TO, 0, 0.55f, -0.45f, 1, -1, 1,
+R_CUBIC_TO, -0.55f, 0, -1, -0.45f, -1, -1,
+R_CUBIC_TO, 0, -0.55f, 0.45f, -1, 1, -1,
+CLOSE,
+R_MOVE_TO, 0, -1.5f,
+R_ARC_TO, 2.5f, 2.5f, 0, 0, 0, 0, 5,
+R_ARC_TO, 2.5f, 2.5f, 0, 0, 0, 0, -5,
+CLOSE,
+R_MOVE_TO, 7, 7.5f,
+R_CUBIC_TO, 0.55f, 0, 1, 0.45f, 1, 1,
+R_CUBIC_TO, 0, 0.55f, -0.45f, 1, -1, 1,
+R_CUBIC_TO, -0.55f, 0, -1, -0.45f, -1, -1,
+R_CUBIC_TO, 0, -0.55f, 0.45f, -1, 1, -1,
+CLOSE,
+R_MOVE_TO, 0, -1.5f,
+R_ARC_TO, 2.5f, 2.5f, 0, 0, 0, 0, 5,
+R_ARC_TO, 2.5f, 2.5f, 0, 0, 0, 0, -5,
+CLOSE
\ No newline at end of file
diff --git a/components/safe_browsing/content/browser/browser_url_loader_throttle.cc b/components/safe_browsing/content/browser/browser_url_loader_throttle.cc
index 32f37e7..bc88b051 100644
--- a/components/safe_browsing/content/browser/browser_url_loader_throttle.cc
+++ b/components/safe_browsing/content/browser/browser_url_loader_throttle.cc
@@ -389,6 +389,10 @@
       "WillRedirectRequestAfterWillProcessResponse",
       will_process_response_count_ > 0);
 
+  safe_browsing::scheme_logger::LogScheme(
+      original_url_,
+      "SafeBrowsing.BrowserThrottle.RedirectedOriginalUrlScheme");
+
   if (blocked_) {
     // OnCheckUrlResult() has set |blocked_| to true and called
     // |delegate_->CancelWithError|, but this method is called before the
diff --git a/components/services/storage/dom_storage/local_storage_impl.cc b/components/services/storage/dom_storage/local_storage_impl.cc
index 3782ff4e..819a718 100644
--- a/components/services/storage/dom_storage/local_storage_impl.cc
+++ b/components/services/storage/dom_storage/local_storage_impl.cc
@@ -751,10 +751,17 @@
   std::vector<blink::StorageKey> storage_keys_to_delete;
   for (const auto& info : usage) {
     const blink::StorageKey& storage_key = info->storage_key;
-    if (storage_key.IsFirstPartyContext()) {
-      const url::Origin& origin = storage_key.origin();
-      if (base::Contains(origins_to_purge_on_shutdown_, origin)) {
+    const url::Origin& key_origin = storage_key.origin();
+    // Delete the storage if its origin matches one of the origins to purge, or
+    // if it is third-party and the top-level site is same-site with one of
+    // those origins.
+    for (const auto& origin_to_purge : origins_to_purge_on_shutdown_) {
+      if (key_origin == origin_to_purge ||
+          (storage_key.IsThirdPartyContext() &&
+           net::SchemefulSite(origin_to_purge) ==
+               storage_key.top_level_site())) {
         storage_keys_to_delete.push_back(storage_key);
+        break;
       }
     }
   }
diff --git a/components/services/storage/dom_storage/local_storage_impl_unittest.cc b/components/services/storage/dom_storage/local_storage_impl_unittest.cc
index ee40564..db13bb9 100644
--- a/components/services/storage/dom_storage/local_storage_impl_unittest.cc
+++ b/components/services/storage/dom_storage/local_storage_impl_unittest.cc
@@ -18,6 +18,7 @@
 #include "base/task/sequenced_task_runner.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/test/bind.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "build/build_config.h"
 #include "components/services/storage/dom_storage/storage_area_test_util.h"
@@ -25,6 +26,7 @@
 #include "components/services/storage/public/cpp/filesystem/filesystem_proxy.h"
 #include "components/services/storage/public/mojom/storage_usage_info.mojom.h"
 #include "mojo/public/cpp/bindings/remote.h"
+#include "net/base/features.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/common/storage_key/storage_key.h"
 #include "third_party/leveldatabase/env_chromium.h"
@@ -706,10 +708,17 @@
 }
 
 TEST_F(LocalStorageImplTest, ShutdownClearsData) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeature(
+      net::features::kThirdPartyStoragePartitioning);
   blink::StorageKey storage_key1 =
       blink::StorageKey::CreateFromStringForTesting("http://foobar.com");
   blink::StorageKey storage_key2 =
       blink::StorageKey::CreateFromStringForTesting("http://example.com");
+  blink::StorageKey storage_key1_third_party = blink::StorageKey::Create(
+      url::Origin::Create(GURL("http://example1.com")),
+      net::SchemefulSite(GURL("http://foobar.com")),
+      blink::mojom::AncestorChainBit::kCrossSite);
   auto key1 = StdStringToUint8Vector("key1");
   auto key2 = StdStringToUint8Vector("key");
   auto value = StdStringToUint8Vector("value");
@@ -725,6 +734,10 @@
   area->Put(key2, value, absl::nullopt, "source", base::DoNothing());
   area.reset();
 
+  context()->BindStorageArea(storage_key1_third_party,
+                             area.BindNewPipeAndPassReceiver());
+  area->Put(key1, value, absl::nullopt, "source", base::DoNothing());
+
   // Make sure all data gets committed to the DB.
   RunUntilIdle();
 
@@ -735,6 +748,9 @@
 
   // Data from storage_key2 should exist, including meta-data, but nothing
   // should exist for storage_key1.
+  // Data from storage_key1_third_party should also be erased, since it is
+  // a third party storage key, and its top_level_site matches the origin
+  // of storage_key1, which is set to purge on shutdown.
   ResetStorage(storage_path());
   auto contents = GetDatabaseContents();
   EXPECT_EQ(3u, contents.size());
@@ -743,6 +759,8 @@
       continue;
     EXPECT_EQ(std::string::npos,
               entry.first.find(storage_key1.origin().Serialize()));
+    EXPECT_EQ(std::string::npos,
+              entry.first.find(storage_key1_third_party.origin().Serialize()));
     EXPECT_NE(std::string::npos,
               entry.first.find(storage_key2.origin().Serialize()));
   }
diff --git a/components/supervised_user/core/browser/web_content_handler.h b/components/supervised_user/core/browser/web_content_handler.h
index c014f4c..558be42 100644
--- a/components/supervised_user/core/browser/web_content_handler.h
+++ b/components/supervised_user/core/browser/web_content_handler.h
@@ -43,6 +43,8 @@
   virtual ~WebContentHandler();
 
   // Initiates the OS specific local approval flow for a given `url`.
+  // Not all platforms with supervised users support this operation,
+  // and they must throw an error when implementing this method.
   virtual void RequestLocalApproval(
       const GURL& url,
       const std::u16string& child_display_name,
@@ -69,8 +71,8 @@
 
  protected:
   // Processes the outcome of the local approval request.
-  // Shared between the platforms. Should be called by platform specific
-  // completion callback.
+  // Should be called by platform specific completion callback.
+  // TODO(b/278079069): Refactor and convert the class to an interface.
   void OnLocalApprovalRequestCompleted(
       supervised_user::SupervisedUserSettingsService& settings_service,
       const GURL& url,
diff --git a/components/supervised_user/core/common/features.cc b/components/supervised_user/core/common/features.cc
index a8c58ff0..4e7742416 100644
--- a/components/supervised_user/core/common/features.cc
+++ b/components/supervised_user/core/common/features.cc
@@ -20,7 +20,19 @@
 BASE_FEATURE(kWebFilterInterstitialRefresh,
              "WebFilterInterstitialRefresh",
              base::FEATURE_DISABLED_BY_DEFAULT);
-#else
+#elif BUILDFLAG(IS_IOS)
+BASE_FEATURE(kWebFilterInterstitialRefresh,
+             "WebFilterInterstitialRefresh",
+             base::FEATURE_ENABLED_BY_DEFAULT);
+#elif BUILDFLAG(IS_CHROMEOS_ASH)
+BASE_FEATURE(kWebFilterInterstitialRefresh,
+             "WebFilterInterstitialRefresh",
+             base::FEATURE_ENABLED_BY_DEFAULT);
+#elif BUILDFLAG(IS_CHROMEOS_LACROS)
+BASE_FEATURE(kWebFilterInterstitialRefresh,
+             "WebFilterInterstitialRefresh",
+             base::FEATURE_ENABLED_BY_DEFAULT);
+#else  // Desktop
 BASE_FEATURE(kWebFilterInterstitialRefresh,
              "WebFilterInterstitialRefresh",
              base::FEATURE_ENABLED_BY_DEFAULT);
@@ -33,12 +45,24 @@
 //
 // The feature includes one experiment parameter: "preferred_button", which
 // determines which button is displayed as the preferred option in the
-// interstitial UI (i.e. dark blue button).
-#if BUILDFLAG(IS_CHROMEOS)
+// interstitial UI (i.e. dark blue button).#if BUILDFLAG(IS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
+BASE_FEATURE(kLocalWebApprovals,
+             "LocalWebApprovals",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+#elif BUILDFLAG(IS_IOS)
+BASE_FEATURE(kLocalWebApprovals,
+             "LocalWebApprovals",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+#elif BUILDFLAG(IS_CHROMEOS_ASH)
 BASE_FEATURE(kLocalWebApprovals,
              "LocalWebApprovals",
              base::FEATURE_ENABLED_BY_DEFAULT);
-#else
+#elif BUILDFLAG(IS_CHROMEOS_LACROS)
+BASE_FEATURE(kLocalWebApprovals,
+             "LocalWebApprovals",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+#else  // Desktop
 BASE_FEATURE(kLocalWebApprovals,
              "LocalWebApprovals",
              base::FEATURE_DISABLED_BY_DEFAULT);
@@ -90,8 +114,8 @@
              base::FEATURE_DISABLED_BY_DEFAULT);
 
 bool IsWebFilterInterstitialRefreshEnabled() {
-  DCHECK(base::FeatureList::IsEnabled(kWebFilterInterstitialRefresh) ||
-         !base::FeatureList::IsEnabled(kLocalWebApprovals));
+  CHECK(base::FeatureList::IsEnabled(kWebFilterInterstitialRefresh) ||
+        !base::FeatureList::IsEnabled(kLocalWebApprovals));
   return base::FeatureList::IsEnabled(kWebFilterInterstitialRefresh);
 }
 
diff --git a/components/supervised_user/core/common/features_unittest.cc b/components/supervised_user/core/common/features_unittest.cc
index 2137c15..e70a52e8 100644
--- a/components/supervised_user/core/common/features_unittest.cc
+++ b/components/supervised_user/core/common/features_unittest.cc
@@ -66,9 +66,8 @@
   EXPECT_FALSE(IsLocalWebApprovalsEnabled());
 }
 
-// Tests that DCHECK is triggered when local web approval feature is enabled
+// Tests that CHECK is triggered when local web approval feature is enabled
 // without the refreshed web filter interstitial layout feature.
-#if DCHECK_IS_ON()
 TEST_F(LocalWebApprovalsFeatureTest,
        InterstitialRefreshDisableAndLocalApprovalsEnabled) {
   scoped_feature_list_.InitWithFeatures(
@@ -77,6 +76,5 @@
   EXPECT_DEATH_IF_SUPPORTED(IsWebFilterInterstitialRefreshEnabled(), "");
   EXPECT_DEATH_IF_SUPPORTED(IsLocalWebApprovalsEnabled(), "");
 }
-#endif
 
 }  // namespace supervised_user
diff --git a/components/sync/driver/resources/about.ts b/components/sync/driver/resources/about.ts
index 5f865fb..e15f3e7 100644
--- a/components/sync/driver/resources/about.ts
+++ b/components/sync/driver/resources/about.ts
@@ -7,7 +7,7 @@
 import {assert} from 'chrome://resources/js/assert_ts.js';
 import {addWebUiListener, removeWebUiListener, WebUiListener} from 'chrome://resources/js/cr.js';
 
-import {requestDataAndRegisterForUpdates, requestStart, requestStopClearData, requestStopKeepData, setIncludeSpecifics, triggerRefresh} from './chrome_sync.js';
+import {requestDataAndRegisterForUpdates, requestStart, requestStopClearData, setIncludeSpecifics, triggerRefresh} from './chrome_sync.js';
 import {ProtocolEvent} from './traffic_log.js';
 
 // Contains the latest snapshot of sync about info.
@@ -266,10 +266,6 @@
   const requestStartEl = document.querySelector<HTMLElement>('#request-start');
   assert(requestStartEl);
   requestStartEl.addEventListener('click', requestStart);
-  const requestStopKeepDataEl =
-      document.querySelector<HTMLElement>('#request-stop-keep-data');
-  assert(requestStopKeepDataEl);
-  requestStopKeepDataEl.addEventListener('click', requestStopKeepData);
   const requestStopClearDataEl =
       document.querySelector<HTMLElement>('#request-stop-clear-data');
   assert(requestStopClearDataEl);
diff --git a/components/sync/driver/resources/chrome_sync.ts b/components/sync/driver/resources/chrome_sync.ts
index 72030e6d..20e7a10 100644
--- a/components/sync/driver/resources/chrome_sync.ts
+++ b/components/sync/driver/resources/chrome_sync.ts
@@ -78,13 +78,6 @@
 }
 
 /**
- * Stops the SyncService while keeping the sync data around.
- */
-export function requestStopKeepData() {
-  chrome.send('requestStopKeepData');
-}
-
-/**
  * Stops the SyncService and clears the sync data.
  */
 export function requestStopClearData() {
diff --git a/components/sync/driver/resources/index.html b/components/sync/driver/resources/index.html
index 1d73f27a..444fdc4b9 100644
--- a/components/sync/driver/resources/index.html
+++ b/components/sync/driver/resources/index.html
@@ -68,8 +68,7 @@
 
       <div id="request-start-stop-wrapper" jsskip="true">
         <button id="request-start">Request Start</button>
-        <button id="request-stop-keep-data">Stop Sync (Keep Data)</button>
-        <button id="request-stop-clear-data">Disable Sync (Clear Data)</button>
+        <button id="request-stop-clear-data">Disable Sync</button>
       </div>
 
       <div id="traffic-event-container-wrapper" jsskip="true">
diff --git a/components/sync/driver/sync_internals_util.h b/components/sync/driver/sync_internals_util.h
index cc53ff6a..0b54df95 100644
--- a/components/sync/driver/sync_internals_util.h
+++ b/components/sync/driver/sync_internals_util.h
@@ -47,7 +47,6 @@
     "requestIncludeSpecificsInitialState";
 inline constexpr char kRequestListOfTypes[] = "requestListOfTypes";
 inline constexpr char kRequestStart[] = "requestStart";
-inline constexpr char kRequestStopKeepData[] = "requestStopKeepData";
 inline constexpr char kRequestStopClearData[] = "requestStopClearData";
 inline constexpr char kSetIncludeSpecifics[] = "setIncludeSpecifics";
 inline constexpr char kTriggerRefresh[] = "triggerRefresh";
diff --git a/components/version_ui_strings.grdp b/components/version_ui_strings.grdp
index cc5f082..6a643c6 100644
--- a/components/version_ui_strings.grdp
+++ b/components/version_ui_strings.grdp
@@ -22,10 +22,20 @@
     <message name="IDS_VERSION_UI_64BIT_TRANSLATED_INTEL" desc="On the chrome://version page, an indicator that this is an instance of Chromium built for the 64-bit x86 processor, but being run on an Arm processor. Do not translate 'x86_64' as that is a technical term. The 'translated' in this string refers to the fact that these two processors use different languages, so the sense of 'translated' for this string is as in a language translation.">
       (x86_64 translated)
     </message>
+  </if>
+  <if expr="is_macosx or is_win">
     <message name="IDS_VERSION_UI_64BIT_ARM" desc="On the chrome://version page, an indicator that this is an instance of Chromium built for the 64-bit Arm processor. Translation is not needed; this is a technical term.">
       (arm64)
     </message>
   </if>
+  <if expr="is_win">
+    <message name="IDS_VERSION_UI_32BIT_TRANSLATED_INTEL" desc="On the chrome://version page, an indicator that this is an instance of Chromium built for the 32-bit x86 processor, but being run on an Arm processor. Do not translate.">
+      (32-bit emulated)
+    </message>
+    <message name="IDS_VERSION_UI_64BIT_TRANSLATED_INTEL" desc="On the chrome://version page, an indicator that this is an instance of Chromium built for the 64-bit x86 processor, but being run on an Arm processor. Do not translate.">
+      (64-bit emulated)
+    </message>
+  </if>
   <message name="IDS_VERSION_UI_REVISION" desc="label for the revision on the about:version page">
     Revision
   </message>
diff --git a/components/viz/common/features.cc b/components/viz/common/features.cc
index 292c7aa..829b6fd 100644
--- a/components/viz/common/features.cc
+++ b/components/viz/common/features.cc
@@ -154,14 +154,22 @@
              base::FEATURE_DISABLED_BY_DEFAULT);
 
 #if BUILDFLAG(IS_APPLE)
-BASE_FEATURE(kMacCAOverlayQuad,
-             "MacCAOverlayQuads",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-// The maximum supported overlay quad number on Mac CALayerOverlay.
-// The default is set to -1. When MaxNum is < 0, the default in CALayerOverlay
-// will be used instead.
-const base::FeatureParam<int> kMacCAOverlayQuadMaxNum{
-    &kMacCAOverlayQuad, "MacCAOverlayQuadMaxNum", -1};
+// Increase the max CALayer number allowed for CoreAnimation.
+// * If this feature is disabled, then the default limit is 128 quads,
+//   unless there are 5 or more video elements present, in which case
+//   the limit is 300.
+// * If this feature is enabled, then these limits are 512 and 300 quads
+//   respectively, and can be overridden by the "default" and "many-videos"
+//   feature parameters.
+BASE_FEATURE(kCALayerNewLimit,
+             "CALayerNewLimit",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+// Set FeatureParam default to -1. CALayerOverlayProcessor choose the default in
+// ca_layer_overlay.cc When it's < 0.
+const base::FeatureParam<int> kCALayerNewLimitDefault{&kCALayerNewLimit,
+                                                      "default", -1};
+const base::FeatureParam<int> kCALayerNewLimitManyVideos{&kCALayerNewLimit,
+                                                         "many-videos", -1};
 #endif
 
 #if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_OZONE)
diff --git a/components/viz/common/features.h b/components/viz/common/features.h
index 9687e2ee..eeec9b4 100644
--- a/components/viz/common/features.h
+++ b/components/viz/common/features.h
@@ -45,8 +45,10 @@
 VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kDynamicSchedulerForDraw);
 VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kDynamicSchedulerForClients);
 #if BUILDFLAG(IS_APPLE)
-VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kMacCAOverlayQuad);
-VIZ_COMMON_EXPORT extern const base::FeatureParam<int> kMacCAOverlayQuadMaxNum;
+VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kCALayerNewLimit);
+VIZ_COMMON_EXPORT extern const base::FeatureParam<int> kCALayerNewLimitDefault;
+VIZ_COMMON_EXPORT extern const base::FeatureParam<int>
+    kCALayerNewLimitManyVideos;
 #endif
 
 #if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_OZONE)
diff --git a/components/viz/common/frame_sinks/begin_frame_source.cc b/components/viz/common/frame_sinks/begin_frame_source.cc
index 6ec52f95..855261e 100644
--- a/components/viz/common/frame_sinks/begin_frame_source.cc
+++ b/components/viz/common/frame_sinks/begin_frame_source.cc
@@ -15,6 +15,7 @@
 #include "base/check_op.h"
 #include "base/containers/contains.h"
 #include "base/location.h"
+#include "base/metrics/histogram_macros.h"
 #include "base/notreached.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/strings/string_number_conversions.h"
@@ -166,14 +167,20 @@
   is_gpu_busy_ = busy;
   if (is_gpu_busy_) {
     DCHECK_EQ(gpu_busy_response_state_, GpuBusyThrottlingState::kIdle);
+    gpu_busy_start_time_ = base::TimeTicks::Now();
     return;
   }
 
   const bool was_throttled =
       gpu_busy_response_state_ == GpuBusyThrottlingState::kThrottled;
   gpu_busy_response_state_ = GpuBusyThrottlingState::kIdle;
-  if (was_throttled)
+  if (was_throttled) {
+    UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(
+        "Viz.FrameSink.GpuBusyDuration",
+        base::TimeTicks::Now() - gpu_busy_start_time_, base::Microseconds(1),
+        base::Seconds(5), /*bucket_count=*/100);
     OnGpuNoLongerBusy();
+  }
 }
 
 bool BeginFrameSource::RequestCallbackOnGpuAvailable() {
diff --git a/components/viz/common/frame_sinks/begin_frame_source.h b/components/viz/common/frame_sinks/begin_frame_source.h
index d270a96..89dd9a2c 100644
--- a/components/viz/common/frame_sinks/begin_frame_source.h
+++ b/components/viz/common/frame_sinks/begin_frame_source.h
@@ -244,6 +244,7 @@
   // The BeginFrameSource should not send the begin-frame messages to clients if
   // gpu is busy.
   bool is_gpu_busy_ = false;
+  base::TimeTicks gpu_busy_start_time_;
 
   // Keeps track of whether a begin-frame was paused, and whether
   // OnGpuNoLongerBusy() should be invoked when the gpu is no longer busy.
diff --git a/components/viz/service/display/ca_layer_overlay.cc b/components/viz/service/display/ca_layer_overlay.cc
index 6780495..3cac8b41 100644
--- a/components/viz/service/display/ca_layer_overlay.cc
+++ b/components/viz/service/display/ca_layer_overlay.cc
@@ -30,10 +30,18 @@
 // quads are promoted to CALayers. At extremes, corruption can occur.
 // https://crbug.com/1022116
 
-constexpr size_t kTooManyQuads = 128;
-// |kTooManyQuadsWithVideos| can be re-assigned by kMacCAOverlayQuadMaxNum when
-// feature kMacCAOverlayQuad is enabled.
-constexpr size_t kTooManyQuadsWithVideos = 300;
+// The default CALayer number allowed for CoreAnimation when kCALayerNewLimit is
+// disabled.
+constexpr size_t kLayerLimitDefault = 128;
+
+// The default CALayer number allowed with many videos (video conferencing). It
+// can be overriden by the "many-videos" feature parameters if kCALayerNewLimit
+// is enabled.
+constexpr size_t kLayerLimitWithManyVideos = 300;
+
+// The new limit if kCALayerNewLimit is enabled. It can be overriden by the
+// "default" feature parameters.
+constexpr size_t kLayerNewLimitDefault = 512;
 
 // If there are too many RenderPassDrawQuads, we shouldn't use Core
 // Animation to present them as individual layers, since that potentially
@@ -368,16 +376,22 @@
     : overlays_allowed_(ui::RemoteLayerAPISupported()),
       enable_ca_renderer_(base::FeatureList::IsEnabled(kCARenderer)),
       enable_hdr_underlays_(base::FeatureList::IsEnabled(kHDRUnderlays)) {
-  if (base::FeatureList::IsEnabled(features::kMacCAOverlayQuad)) {
-    max_quad_list_size_for_videos_ = kTooManyQuadsWithVideos;
-    const int max_num = features::kMacCAOverlayQuadMaxNum.Get();
-    if (max_num > 0)
-      max_quad_list_size_for_videos_ = max_num;
-  } else {
-    max_quad_list_size_for_videos_ = kTooManyQuads;
-  }
+  layer_limit_default_ = kLayerLimitDefault;
+  layer_limit_with_many_videos_ = kLayerLimitWithManyVideos;
+  if (base::FeatureList::IsEnabled(features::kCALayerNewLimit)) {
+    layer_limit_default_ = kLayerNewLimitDefault;
+    const int layer_limit_default_field_trial =
+        features::kCALayerNewLimitDefault.Get();
+    if (layer_limit_default_field_trial > 0) {
+      layer_limit_default_ = layer_limit_default_field_trial;
+    }
 
-  DCHECK_GE(max_quad_list_size_for_videos_, kTooManyQuads);
+    const int layer_limit_with_many_videos_field_trial =
+        features::kCALayerNewLimitManyVideos.Get();
+    if (layer_limit_with_many_videos_field_trial > 0) {
+      layer_limit_with_many_videos_ = layer_limit_with_many_videos_field_trial;
+    }
+  }
 }
 
 bool CALayerOverlayProcessor::AreClipSettingsValid(
@@ -478,8 +492,6 @@
     result = gfx::kCALayerFailedVideoCaptureEnabled;
   } else if (!render_pass->copy_requests.empty()) {
     result = gfx::kCALayerFailedCopyRequests;
-  } else if (num_visible_quads > max_quad_list_size_for_videos_) {
-    result = gfx::kCALayerFailedTooManyQuads;
   }
 
   if (result != gfx::kCALayerSuccess) {
@@ -527,12 +539,11 @@
     ca_layer_overlays->push_back(ca_layer);
   }
 
-  // Apply Feature kMacCAOverlayQuad to non-video-conferencing mode only.
-  // In the case of |max_quad_list_size_for_videos_| > |num_visible_quads| >
-  // kTooManyQuads, accept OverlayCandidate only if it's in a video conferencing
-  // mode. (video count >= kMaxNumVideos(5)) Otherwise, fail OverlayCandidate.
-  if (num_visible_quads > kTooManyQuads &&
-      yuv_draw_quad_count < kMaxNumVideos) {
+  // Fails if there are more draw quads than allowed for CoreAnimation.
+  size_t max_number = (yuv_draw_quad_count < kMaxNumVideos)
+                          ? layer_limit_default_
+                          : layer_limit_with_many_videos_;
+  if (num_visible_quads > max_number) {
     result = gfx::kCALayerFailedTooManyQuads;
   }
 
diff --git a/components/viz/service/display/ca_layer_overlay.h b/components/viz/service/display/ca_layer_overlay.h
index f4d87b6d..c1febf09 100644
--- a/components/viz/service/display/ca_layer_overlay.h
+++ b/components/viz/service/display/ca_layer_overlay.h
@@ -97,7 +97,8 @@
   // https://crbug.com/836351, https://crbug.com/1290384
   bool video_capture_enabled_ = false;
 
-  size_t max_quad_list_size_for_videos_ = 0;
+  size_t layer_limit_with_many_videos_ = 0;
+  size_t layer_limit_default_ = 0;
 
   // The error code in ProcessForCALayerOverlays()
   gfx::CALayerResult ca_layer_result_ = gfx::kCALayerSuccess;
diff --git a/components/viz/service/display/display.cc b/components/viz/service/display/display.cc
index 7f20730..9268c51 100644
--- a/components/viz/service/display/display.cc
+++ b/components/viz/service/display/display.cc
@@ -943,6 +943,9 @@
       scheduler_->DidSwapBuffers();
     pending_swaps_++;
 
+    UMA_HISTOGRAM_COUNTS_100("Compositing.Display.PendingSwaps",
+                             pending_swaps_);
+
     renderer_->SwapBuffers(std::move(swap_frame_data));
   } else {
     TRACE_EVENT_INSTANT0("viz", "Swap skipped.", TRACE_EVENT_SCOPE_THREAD);
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.cc b/components/viz/service/display_embedder/skia_output_surface_impl.cc
index 10c7edd..f4845f6c 100644
--- a/components/viz/service/display_embedder/skia_output_surface_impl.cc
+++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -111,8 +111,8 @@
 }  // namespace
 
 SkiaOutputSurfaceImpl::ScopedPaint::ScopedPaint(
-    SkDeferredDisplayListRecorder* root_recorder)
-    : recorder_(root_recorder) {}
+    SkDeferredDisplayListRecorder* root_ddl_recorder)
+    : ddl_recorder_(root_ddl_recorder) {}
 
 SkiaOutputSurfaceImpl::ScopedPaint::ScopedPaint(
     SkSurfaceCharacterization characterization)
@@ -122,8 +122,8 @@
     SkSurfaceCharacterization characterization,
     gpu::Mailbox mailbox)
     : mailbox_(mailbox) {
-  recorder_storage_.emplace(characterization);
-  recorder_ = &recorder_storage_.value();
+  ddl_recorder_storage_.emplace(characterization);
+  ddl_recorder_ = &ddl_recorder_storage_.value();
 }
 
 SkiaOutputSurfaceImpl::ScopedPaint::~ScopedPaint() = default;
@@ -233,7 +233,7 @@
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   TRACE_EVENT0("viz", __PRETTY_FUNCTION__);
   current_paint_.reset();
-  root_recorder_.reset();
+  root_ddl_recorder_.reset();
 
   if (!render_pass_image_cache_.empty()) {
     std::vector<AggregatedRenderPassId> render_pass_ids;
@@ -311,12 +311,12 @@
   gpu_task_scheduler_->ScheduleOrRetainGpuTask(std::move(callback), {});
 }
 
-void SkiaOutputSurfaceImpl::RecreateRootRecorder() {
+void SkiaOutputSurfaceImpl::RecreateRootDDLRecorder() {
   DCHECK(characterization_.isValid());
-  root_recorder_.emplace(characterization_);
+  root_ddl_recorder_.emplace(characterization_);
   // This will trigger the lazy initialization of the recorder
-  std::ignore = root_recorder_->getCanvas();
-  reset_recorder_on_swap_ = false;
+  std::ignore = root_ddl_recorder_->getCanvas();
+  reset_ddl_recorder_on_swap_ = false;
 }
 
 void SkiaOutputSurfaceImpl::Reshape(const ReshapeParams& params) {
@@ -367,7 +367,7 @@
 
   size_ = params.size;
   format_ = params.format;
-  RecreateRootRecorder();
+  RecreateRootDDLRecorder();
 }
 
 void SkiaOutputSurfaceImpl::SetUpdateVSyncParametersCallback(
@@ -409,10 +409,10 @@
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   // Make sure there is no unsubmitted PaintFrame or PaintRenderPass.
   DCHECK(!current_paint_);
-  DCHECK(root_recorder_);
-  reset_recorder_on_swap_ = true;
-  current_paint_.emplace(&root_recorder_.value());
-  return current_paint_->recorder()->getCanvas();
+  DCHECK(root_ddl_recorder_);
+  reset_ddl_recorder_on_swap_ = true;
+  current_paint_.emplace(&root_ddl_recorder_.value());
+  return current_paint_->ddl_recorder()->getCanvas();
 }
 
 void SkiaOutputSurfaceImpl::MakePromiseSkImage(
@@ -606,11 +606,11 @@
                  /*make_current=*/true,
                  /*need_framebuffer=*/!dependency_->IsOffscreen());
 
-  // Recreate |root_recorder_| after SwapBuffers has been scheduled on GPU
+  // Recreate |root_ddl_recorder_| after SwapBuffers has been scheduled on GPU
   // thread to save some time in BeginPaintCurrentFrame
   // Recreating recorder is expensive. Avoid recreation if there was no paint.
-  if (reset_recorder_on_swap_) {
-    RecreateRootRecorder();
+  if (reset_ddl_recorder_on_swap_) {
+    RecreateRootDDLRecorder();
   }
 }
 
@@ -635,8 +635,8 @@
                  /*make_current=*/true, /*need_framebuffer=*/false);
 
   // Recreating recorder is expensive. Avoid recreation if there was no paint.
-  if (reset_recorder_on_swap_) {
-    RecreateRootRecorder();
+  if (reset_ddl_recorder_on_swap_) {
+    RecreateRootDDLRecorder();
   }
 }
 
@@ -686,7 +686,7 @@
   }
 
   current_paint_.emplace(characterization, mailbox);
-  return current_paint_->recorder()->getCanvas();
+  return current_paint_->ddl_recorder()->getCanvas();
 }
 
 SkCanvas* SkiaOutputSurfaceImpl::RecordOverdrawForCurrentPaint() {
@@ -694,10 +694,10 @@
 
   DCHECK(debug_settings_->show_overdraw_feedback);
   DCHECK(current_paint_);
-  DCHECK(!overdraw_surface_recorder_);
+  DCHECK(!overdraw_surface_ddl_recorder_);
 
   nway_canvas_.emplace(characterization_.width(), characterization_.height());
-  nway_canvas_->addCanvas(current_paint_->recorder()->getCanvas());
+  nway_canvas_->addCanvas(current_paint_->ddl_recorder()->getCanvas());
 
   // Overdraw feedback uses |SkOverdrawCanvas|, which relies on a buffer with an
   // 8-bit unorm alpha channel to work. RGBA8 is always supported, so we use it.
@@ -710,8 +710,8 @@
           /*mipmap=*/false, characterization_.refColorSpace(),
           /*is_overlay=*/false, /*scanout_dcomp_surface=*/false);
   if (characterization.isValid()) {
-    overdraw_surface_recorder_.emplace(characterization);
-    overdraw_canvas_.emplace((overdraw_surface_recorder_->getCanvas()));
+    overdraw_surface_ddl_recorder_.emplace(characterization);
+    overdraw_canvas_.emplace((overdraw_surface_ddl_recorder_->getCanvas()));
     nway_canvas_->addCanvas(&overdraw_canvas_.value());
   }
 
@@ -725,14 +725,14 @@
     bool is_overlay) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(current_paint_);
-  auto ddl = current_paint_->recorder()->detach();
+  auto ddl = current_paint_->ddl_recorder()->detach();
 
   sk_sp<SkDeferredDisplayList> overdraw_ddl;
-  if (overdraw_surface_recorder_) {
-    overdraw_ddl = overdraw_surface_recorder_->detach();
+  if (overdraw_surface_ddl_recorder_) {
+    overdraw_ddl = overdraw_surface_ddl_recorder_->detach();
     DCHECK(overdraw_ddl);
     overdraw_canvas_.reset();
-    overdraw_surface_recorder_.reset();
+    overdraw_surface_ddl_recorder_.reset();
     nway_canvas_.reset();
   }
 
@@ -966,12 +966,18 @@
       std::move(add_child_window_to_browser_callback));
   if (!impl_on_gpu_) {
     *result = false;
-  } else {
-    capabilities_ = impl_on_gpu_->capabilities();
-    is_displayed_as_overlay_ = impl_on_gpu_->IsDisplayedAsOverlay();
-    gr_context_thread_safe_ = impl_on_gpu_->GetGrContextThreadSafeProxy();
-    *result = true;
+    return;
   }
+  capabilities_ = impl_on_gpu_->capabilities();
+  is_displayed_as_overlay_ = impl_on_gpu_->IsDisplayedAsOverlay();
+
+  if (auto* gr_context = dependency_->GetSharedContextState()->gr_context()) {
+    gr_context_thread_safe_ = gr_context->threadSafeProxy();
+  }
+  graphite_recorder_ =
+      dependency_->GetSharedContextState()->viz_compositor_graphite_recorder();
+
+  *result = true;
 }
 
 SkSurfaceCharacterization
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.h b/components/viz/service/display_embedder/skia_output_surface_impl.h
index 148fb4bf..f343b46 100644
--- a/components/viz/service/display_embedder/skia_output_surface_impl.h
+++ b/components/viz/service/display_embedder/skia_output_surface_impl.h
@@ -43,6 +43,10 @@
 struct SwapBuffersCompleteParams;
 }  // namespace gpu
 
+namespace skgpu::graphite {
+class Recorder;
+}  // namespace skgpu::graphite
+
 namespace viz {
 
 class ImageContextImpl;
@@ -239,7 +243,7 @@
       const absl::optional<gpu::VulkanYCbCrInfo>& ycbcr_info);
   void ContextLost();
 
-  void RecreateRootRecorder();
+  void RecreateRootDDLRecorder();
 
   raw_ptr<OutputSurfaceClient> client_ = nullptr;
   bool needs_swap_size_notifications_ = false;
@@ -263,28 +267,28 @@
   gfx::BufferFormat format_;
   int sample_count_ = 1;
   SkSurfaceCharacterization characterization_;
-  bool reset_recorder_on_swap_ = false;
-  absl::optional<SkDeferredDisplayListRecorder> root_recorder_;
+  bool reset_ddl_recorder_on_swap_ = false;
+  absl::optional<SkDeferredDisplayListRecorder> root_ddl_recorder_;
 
   class ScopedPaint {
    public:
-    explicit ScopedPaint(SkDeferredDisplayListRecorder* root_recorder);
+    explicit ScopedPaint(SkDeferredDisplayListRecorder* root_ddl_recorder);
     explicit ScopedPaint(SkSurfaceCharacterization characterization);
     ScopedPaint(SkSurfaceCharacterization characterization,
                 gpu::Mailbox mailbox);
     ~ScopedPaint();
 
-    SkDeferredDisplayListRecorder* recorder() { return recorder_; }
+    SkDeferredDisplayListRecorder* ddl_recorder() { return ddl_recorder_; }
     gpu::Mailbox mailbox() { return mailbox_; }
 
    private:
     // This is recorder being used for current paint
     // This field is not a raw_ptr<> because it was filtered by the rewriter
     // for: #union
-    RAW_PTR_EXCLUSION SkDeferredDisplayListRecorder* recorder_;
+    RAW_PTR_EXCLUSION SkDeferredDisplayListRecorder* ddl_recorder_;
     // If we need new recorder for this Paint (i.e. it's not root render pass),
     // it's stored here
-    absl::optional<SkDeferredDisplayListRecorder> recorder_storage_;
+    absl::optional<SkDeferredDisplayListRecorder> ddl_recorder_storage_;
     const gpu::Mailbox mailbox_;
   };
 
@@ -322,7 +326,7 @@
   // The SkDDL recorder is used for overdraw feedback. It is created by
   // BeginPaintOverdraw, and FinishPaintCurrentFrame will turn it into a SkDDL
   // and play the SkDDL back on the GPU thread.
-  absl::optional<SkDeferredDisplayListRecorder> overdraw_surface_recorder_;
+  absl::optional<SkDeferredDisplayListRecorder> overdraw_surface_ddl_recorder_;
 
   // |overdraw_canvas_| is used to record draw counts.
   absl::optional<SkOverdrawCanvas> overdraw_canvas_;
@@ -376,6 +380,7 @@
   std::unique_ptr<SkiaOutputSurfaceImplOnGpu> impl_on_gpu_;
 
   sk_sp<GrContextThreadSafeProxy> gr_context_thread_safe_;
+  raw_ptr<skgpu::graphite::Recorder> graphite_recorder_ = nullptr;
 
   bool has_set_draw_rectangle_for_frame_ = false;
   absl::optional<gfx::Rect> draw_rectangle_;
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
index 76ae090..2802fe1 100644
--- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
+++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -1618,11 +1618,6 @@
     context->EndAccessIfNecessary();
 }
 
-sk_sp<GrContextThreadSafeProxy>
-SkiaOutputSurfaceImplOnGpu::GetGrContextThreadSafeProxy() {
-  return gr_context() ? gr_context()->threadSafeProxy() : nullptr;
-}
-
 void SkiaOutputSurfaceImplOnGpu::ReleaseImageContexts(
     std::vector<std::unique_ptr<ExternalUseClient::ImageContext>>
         image_contexts) {
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
index c539eb7..fc9af64 100644
--- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
+++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
@@ -201,7 +201,6 @@
   void ResetStateOfImages();
   void EndAccessImages(const base::flat_set<ImageContextImpl*>& image_contexts);
 
-  sk_sp<GrContextThreadSafeProxy> GetGrContextThreadSafeProxy();
   size_t max_resource_cache_bytes() const { return max_resource_cache_bytes_; }
   void ReleaseImageContexts(
       std::vector<std::unique_ptr<ExternalUseClient::ImageContext>>
diff --git a/components/webauthn/android/fido2credentialrequest_native_android.cc b/components/webauthn/android/fido2credentialrequest_native_android.cc
index 063a0bf..2690b85 100644
--- a/components/webauthn/android/fido2credentialrequest_native_android.cc
+++ b/components/webauthn/android/fido2credentialrequest_native_android.cc
@@ -74,3 +74,19 @@
   return MojoClassFromJSON<blink::mojom::MakeCredentialAuthenticatorResponse>(
       env, webauthn::MakeCredentialResponseFromValue, jjson);
 }
+
+static base::android::ScopedJavaLocalRef<jstring>
+JNI_Fido2CredentialRequest_GetOptionsToJson(
+    JNIEnv* env,
+    const base::android::JavaParamRef<jobject>& byte_buffer) {
+  return MojoClassToJSON<blink::mojom::PublicKeyCredentialRequestOptions>(
+      env, byte_buffer);
+}
+
+static base::android::ScopedJavaLocalRef<jbyteArray>
+JNI_Fido2CredentialRequest_GetCredentialResponseFromJson(
+    JNIEnv* env,
+    const base::android::JavaParamRef<jstring>& jjson) {
+  return MojoClassFromJSON<blink::mojom::GetAssertionAuthenticatorResponse>(
+      env, webauthn::GetAssertionResponseFromValue, jjson);
+}
diff --git a/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2CredentialRequest.java b/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2CredentialRequest.java
index 5d325057..45b3c4d 100644
--- a/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2CredentialRequest.java
+++ b/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2CredentialRequest.java
@@ -203,6 +203,7 @@
         returnErrorAndResetCallback(AuthenticatorStatus.NOT_ALLOWED_ERROR);
     }
 
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
     public void handleGetAssertionRequest(PublicKeyCredentialRequestOptions options,
             RenderFrameHost frameHost, Origin callerOrigin, PaymentOptions payment,
             GetAssertionResponseCallback callback, FidoErrorResponseCallback errorCallback) {
@@ -213,12 +214,6 @@
             mWebContents = WebContentsStatics.fromRenderFrameHost(frameHost);
         }
 
-        if (!apiAvailable()) {
-            Log.e(TAG, "Google Play Services' Fido2PrivilegedApi is not available.");
-            returnErrorAndResetCallback(AuthenticatorStatus.UNKNOWN_ERROR);
-            return;
-        }
-
         WebAuthSecurityChecksResults webAuthSecurityChecksResults =
                 frameHost.performGetAssertionWebAuthSecurityChecks(
                         options.relyingPartyId, callerOrigin, payment != null);
@@ -242,6 +237,19 @@
         String callerOriginString = convertOriginToString(callerOrigin);
         byte[] clientDataHash = null;
 
+        // Conditional requests and payments should still go through Google Play Services.
+        if (!options.isConditional && payment == null && isCredManEnabled()
+                && BuildCompat.isAtLeastU()) {
+            getCredentialViaCredMan(options, callerOrigin, frameHost);
+            return;
+        }
+
+        if (!apiAvailable()) {
+            Log.e(TAG, "Google Play Services' Fido2PrivilegedApi is not available.");
+            returnErrorAndResetCallback(AuthenticatorStatus.UNKNOWN_ERROR);
+            return;
+        }
+
         if (payment != null
                 && PaymentFeatureList.isEnabled(PaymentFeatureList.SECURE_PAYMENT_CONFIRMATION)) {
             assert options.challenge != null;
@@ -649,8 +657,11 @@
         mWebContents = webContents;
     }
 
-    /** Create a credential using the Android 14 CredMan API. */
-    @RequiresApi(Build.VERSION_CODES.S)
+    /**
+     * Create a credential using the Android 14 CredMan API.
+     * TODO: update the version code to U when Chromium builds with Android 14 SDK.
+     */
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
     @SuppressWarnings("WrongConstant")
     private void makeCredentialViaCredMan(
             PublicKeyCredentialCreationOptions options, Origin origin, RenderFrameHost frameHost) {
@@ -742,9 +753,143 @@
         }
     }
 
+    /**
+     * Gets the credential using the Android 14 CredMan API.
+     * TODO: update the version code to U when Chromium builds with Android 14 SDK.
+     */
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+    @SuppressWarnings("WrongConstant")
+    private void getCredentialViaCredMan(
+            PublicKeyCredentialRequestOptions options, Origin origin, RenderFrameHost frameHost) {
+        final String requestAsJson =
+                Fido2CredentialRequestJni.get().getOptionsToJson(options.serialize());
+        final Context context = ContextUtils.getApplicationContext();
+
+        final Bundle publicKeyCredentialOptionBundle = new Bundle();
+        publicKeyCredentialOptionBundle.putString(CRED_MAN_PREFIX + "BUNDLE_KEY_SUBTYPE",
+                CRED_MAN_PREFIX + "BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION");
+        publicKeyCredentialOptionBundle.putString(
+                CRED_MAN_PREFIX + "BUNDLE_KEY_REQUEST_JSON", requestAsJson);
+        publicKeyCredentialOptionBundle.putString(
+                CRED_MAN_PREFIX + "BUNDLE_KEY_CLIENT_DATA_HASH", null);
+        publicKeyCredentialOptionBundle.putBoolean(
+                CRED_MAN_PREFIX + "BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS", false);
+
+        // The Android 14 APIs have to be called via reflection until Chromium
+        // builds with the Android 14 SDK by default.
+        OutcomeReceiver<Object, Throwable> receiver = new OutcomeReceiver<>() {
+            @Override
+            public void onError(Throwable getCredentialException) {
+                try {
+                    Log.e(TAG, "CredMan call failed", getCredentialException);
+                    Class<?> getCredentialExceptionClass = getCredentialException.getClass();
+                    String errorType =
+                            (String) getCredentialExceptionClass.getMethod("getType").invoke(
+                                    getCredentialException);
+                    if (((String) getCredentialExceptionClass.getField("TYPE_USER_CANCELED")
+                                        .get(getCredentialException))
+                                    .equals(errorType)) {
+                        returnErrorAndResetCallback(AuthenticatorStatus.NOT_ALLOWED_ERROR);
+                        return;
+                    }
+                    returnErrorAndResetCallback(AuthenticatorStatus.UNKNOWN_ERROR);
+                } catch (ReflectiveOperationException e) {
+                    Log.e(TAG, "Reflection failed; are you running on Android 14?",
+                            getCredentialException);
+                    returnErrorAndResetCallback(AuthenticatorStatus.ANDROID_NOT_SUPPORTED_ERROR);
+                }
+            }
+
+            @Override
+            public void onResult(Object getCredentialResponse) {
+                Bundle data;
+                try {
+                    Object credential = getCredentialResponse.getClass()
+                                                .getMethod("getCredential")
+                                                .invoke(getCredentialResponse);
+                    data = (Bundle) credential.getClass().getMethod("getData").invoke(credential);
+
+                } catch (ReflectiveOperationException e) {
+                    Log.e(TAG, "Reflection failed; are you running on Android 14?", e);
+                    returnErrorAndResetCallback(AuthenticatorStatus.UNKNOWN_ERROR);
+                    return;
+                }
+
+                String json =
+                        data.getString(CRED_MAN_PREFIX + "BUNDLE_KEY_AUTHENTICATION_RESPONSE_JSON");
+                byte[] responseSerialized =
+                        Fido2CredentialRequestJni.get().getCredentialResponseFromJson(json);
+                if (responseSerialized == null) {
+                    Log.e(TAG, "Failed to convert response from CredMan to Mojo object");
+                    returnErrorAndResetCallback(AuthenticatorStatus.UNKNOWN_ERROR);
+                    return;
+                }
+
+                GetAssertionAuthenticatorResponse response =
+                        GetAssertionAuthenticatorResponse.deserialize(
+                                ByteBuffer.wrap(responseSerialized));
+                if (response == null) {
+                    Log.e(TAG, "Failed to parse Mojo object");
+                    returnErrorAndResetCallback(AuthenticatorStatus.UNKNOWN_ERROR);
+                    return;
+                }
+                if (mAppIdExtensionUsed) {
+                    response.echoAppidExtension = mAppIdExtensionUsed;
+                }
+                mGetAssertionCallback.onSignResponse(AuthenticatorStatus.SUCCESS, response);
+                mGetAssertionCallback = null;
+            }
+        };
+
+        try {
+            // Build the CredentialOption:
+            final Class<?> credentialOptionBuilderClass =
+                    Class.forName("android.credentials.CredentialOption$Builder");
+            final Object credentialOptionBuilder =
+                    credentialOptionBuilderClass
+                            .getConstructor(String.class, Bundle.class, Bundle.class)
+                            .newInstance(CRED_MAN_PREFIX + "TYPE_PUBLIC_KEY_CREDENTIAL",
+                                    publicKeyCredentialOptionBundle,
+                                    publicKeyCredentialOptionBundle);
+            final Object credentialOption =
+                    credentialOptionBuilderClass.getMethod("build").invoke(credentialOptionBuilder);
+
+            // Build the GetCredentialRequest:
+            final Class<?> getCredentialRequestBuilderClass =
+                    Class.forName("android.credentials.GetCredentialRequest$Builder");
+            final Object getCredentialRequestBuilderObject =
+                    getCredentialRequestBuilderClass.getConstructor(Bundle.class)
+                            .newInstance(new Bundle());
+            getCredentialRequestBuilderClass
+                    .getMethod("addCredentialOption", credentialOption.getClass())
+                    .invoke(getCredentialRequestBuilderObject, credentialOption);
+            getCredentialRequestBuilderClass.getMethod("setOrigin", String.class)
+                    .invoke(getCredentialRequestBuilderObject, convertOriginToString(origin));
+            final Object getCredentialRequest =
+                    getCredentialRequestBuilderClass.getMethod("build").invoke(
+                            getCredentialRequestBuilderObject);
+
+            // TODO: switch "credential" to `Context.CREDENTIAL_SERVICE` and remove the
+            // `@SuppressWarnings` when the Android U SDK is available.
+            final Object manager = context.getSystemService("credential");
+            manager.getClass()
+                    .getMethod("getCredential", Context.class, getCredentialRequest.getClass(),
+                            android.os.CancellationSignal.class,
+                            java.util.concurrent.Executor.class, OutcomeReceiver.class)
+                    .invoke(manager, context, getCredentialRequest, null, context.getMainExecutor(),
+                            receiver);
+        } catch (ReflectiveOperationException e) {
+            Log.e(TAG, "Reflection failed; are you running on Android 14?", e);
+            returnErrorAndResetCallback(AuthenticatorStatus.UNKNOWN_ERROR);
+            return;
+        }
+    }
+
     @NativeMethods
     interface Natives {
         String createOptionsToJson(ByteBuffer serializedOptions);
         byte[] makeCredentialResponseFromJson(String json);
+        String getOptionsToJson(ByteBuffer serializedOptions);
+        byte[] getCredentialResponseFromJson(String json);
     }
 }
diff --git a/components/webauthn/json/value_conversions_unittest.cc b/components/webauthn/json/value_conversions_unittest.cc
index fc162b0..0d07aff45 100644
--- a/components/webauthn/json/value_conversions_unittest.cc
+++ b/components/webauthn/json/value_conversions_unittest.cc
@@ -90,7 +90,7 @@
           device::ResidentKeyRequirement::kRequired,
           device::UserVerificationRequirement::kRequired),
       device::AttestationConveyancePreference::kDirect,
-      /*cable_registration_data=*/nullptr, /*hmac_create_secret=*/true,
+      /*hmac_create_secret=*/true,
       /*prf_enable=*/false, blink::mojom::ProtectionPolicy::UV_REQUIRED,
       /*enforce_protection_policy=*/true,
       /*appid_exclude=*/kAppId,
diff --git a/components/zucchini/equivalence_map.cc b/components/zucchini/equivalence_map.cc
index 26baf368..edc19ec 100644
--- a/components/zucchini/equivalence_map.cc
+++ b/components/zucchini/equivalence_map.cc
@@ -325,6 +325,7 @@
     if (current->length == 0) {
       continue;
     }
+    offset_t current_src_end = current->src_end();
 
     // A "reaper" is an equivalence after |current| that overlaps with it, but
     // is longer, and so truncates |current|.  For example:
@@ -342,12 +343,13 @@
     auto next = current + 1;
     for (; next != equivalences->end(); ++next) {
       DCHECK_GE(next->src_offset, current->src_offset);
-      if (next->src_offset >= current->src_end())
+      if (next->src_offset >= current_src_end) {
         break;  // No more overlap.
+      }
 
       if (current->length < next->length) {
         // |next| is better: So it is a reaper that shrinks |current|.
-        offset_t delta = current->src_end() - next->src_offset;
+        offset_t delta = current_src_end - next->src_offset;
         current->length -= delta;
         next_is_reaper = true;
         break;
@@ -363,20 +365,17 @@
       // Shrink all equivalences that overlap with |current|. These are all
       // worse (same length or shorter), since no reaper is found.
       for (auto reduced = current + 1; reduced != next; ++reduced) {
-        //                Clipping Case 1:     Clipping Case 2:
-        // |current|        cccccccc             cccccccc
-        // |reduced|             rrrrr             rrrr
-        // New |reduced|            rr             (empty)
-        // |delta|          3                    6
-        // |capped_delta|   3                    4
-        offset_t delta = current->src_end() - reduced->src_offset;
+        offset_t delta = current_src_end - reduced->src_offset;
         offset_t capped_delta = std::min(reduced->length, delta);
+        // Use |capped_delta| so length is >= 0 always.
         reduced->length -= capped_delta;
-        // For Case 1, below is same as adding |delta|. For Case 2, offsets
-        // become irrelevant. However, |dst_offset + delta| may create an offset
-        // outside the file, or even overflow. So for robustness,
-        // |capped_delta| is used.
-        reduced->src_offset += capped_delta;
+        // Truncate while preserving sort order re. |src_offset|. This is same
+        // as |reduced->src_offset += delta|.
+        reduced->src_offset = current_src_end;
+        // If the range becomes empty, |+= delta| may cause new |dst_offset| to
+        // overflow (although the value won't get used). To prevent this (for
+        // robustness), use |+= capped_delta|, which is identical to |+= delta|
+        // if the range remains non-empty.
         reduced->dst_offset += capped_delta;
       }
     }
diff --git a/components/zucchini/equivalence_map_unittest.cc b/components/zucchini/equivalence_map_unittest.cc
index 78179e98..2d37be9e 100644
--- a/components/zucchini/equivalence_map_unittest.cc
+++ b/components/zucchini/equivalence_map_unittest.cc
@@ -276,6 +276,10 @@
   EXPECT_EQ(std::deque<Equivalence>({{0, 10, 3}, {3, 16, 2}}),
             PruneEquivalencesAndSortBySourceTest(
                 {{0, 10, 3}, {1, 13, 3}, {3, 16, 2}}));  // Pruning is greedy
+  // Test for crbug.com/1432457.
+  EXPECT_EQ(std::deque<Equivalence>({{0, 10, +6}, {6, 23, +2}}),
+            PruneEquivalencesAndSortBySourceTest(
+                {{0, 10, +6}, {3, 20, +5}, {3, 30, +1}}));
 
   // Consider following pattern that may cause O(n^2) behavior if not handled
   // properly.
diff --git a/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.mm b/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.mm
index 299e3e8..f14cd49b 100644
--- a/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.mm
+++ b/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.mm
@@ -4,6 +4,9 @@
 
 #import "content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.h"
 
+#include <Foundation/Foundation.h>
+
+#include "base/mac/foundation_util.h"
 #include "base/mac/scoped_cftyperef.h"
 #include "base/strings/sys_string_conversions.h"
 #include "components/remote_cocoa/app_shim/ns_view_ids.h"
@@ -262,9 +265,12 @@
 void RenderWidgetHostNSViewBridge::ShowDictionaryOverlay(
     ui::mojom::AttributedStringPtr attributed_string,
     const gfx::Point& baseline_point) {
-  NSAttributedString* string = attributed_string.To<NSAttributedString*>();
-  if ([string length] == 0)
+  CFAttributedStringRef cf_string =
+      attributed_string.To<CFAttributedStringRef>();
+  NSAttributedString* string = base::mac::CFToNSCast(cf_string);
+  if ([string length] == 0) {
     return;
+  }
   NSPoint flipped_baseline_point = {
       static_cast<CGFloat>(baseline_point.x()),
       [cocoa_view_ frame].size.height - baseline_point.y(),
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 3ac97b6..64545f6 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -2287,6 +2287,8 @@
     "webui/web_ui_impl.h",
     "webui/web_ui_main_frame_observer.cc",
     "webui/web_ui_main_frame_observer.h",
+    "webui/web_ui_managed_interface.cc",
+    "webui/web_ui_managed_interface.h",
     "webui/web_ui_message_handler.cc",
     "webui/web_ui_url_loader_factory.cc",
     "worker_host/dedicated_worker_host.cc",
diff --git a/content/browser/devtools/devtools_instrumentation.cc b/content/browser/devtools/devtools_instrumentation.cc
index 1a297b4..b485fd06 100644
--- a/content/browser/devtools/devtools_instrumentation.cc
+++ b/content/browser/devtools/devtools_instrumentation.cc
@@ -330,6 +330,30 @@
   return deprecation_issue;
 }
 
+std::unique_ptr<protocol::Audits::InspectorIssue> BuildBounceTrackingIssue(
+    const blink::mojom::BounceTrackingIssueDetailsPtr& issue_details) {
+  auto bounce_tracking_issue_details =
+      protocol::Audits::BounceTrackingIssueDetails::Create()
+          .SetTrackingSites(std::make_unique<protocol::Array<protocol::String>>(
+              issue_details->tracking_sites))
+          .Build();
+
+  auto protocol_issue_details =
+      protocol::Audits::InspectorIssueDetails::Create()
+          .SetBounceTrackingIssueDetails(
+              std::move(bounce_tracking_issue_details))
+          .Build();
+
+  auto issue =
+      protocol::Audits::InspectorIssue::Create()
+          .SetCode(
+              protocol::Audits::InspectorIssueCodeEnum::BounceTrackingIssue)
+          .SetDetails(std::move(protocol_issue_details))
+          .Build();
+
+  return issue;
+}
+
 void UpdateChildFrameTrees(FrameTreeNode* ftn, bool update_target_info) {
   if (auto* agent_host = WebContentsDevToolsAgentHost::GetFor(
           WebContentsImpl::FromFrameTreeNode(ftn))) {
@@ -1501,6 +1525,10 @@
   } else if (info->code ==
              blink::mojom::InspectorIssueCode::kDeprecationIssue) {
     issue = BuildDeprecationIssue(info->details->deprecation_issue_details);
+  } else if (info->code ==
+             blink::mojom::InspectorIssueCode::kBounceTrackingIssue) {
+    issue =
+        BuildBounceTrackingIssue(info->details->bounce_tracking_issue_details);
   } else {
     NOTREACHED() << "Unsupported type of browser-initiated issue";
   }
diff --git a/content/browser/gpu/compositor_util.cc b/content/browser/gpu/compositor_util.cc
index 2dfdb62..18ba841 100644
--- a/content/browser/gpu/compositor_util.cc
+++ b/content/browser/gpu/compositor_util.cc
@@ -293,8 +293,9 @@
       if (gpu_feature_data.name == "multiple_raster_threads") {
         const base::CommandLine& command_line =
             *base::CommandLine::ForCurrentProcess();
-        if (command_line.HasSwitch(blink::switches::kNumRasterThreads))
+        if (command_line.HasSwitch(cc::switches::kNumRasterThreads)) {
           status += "_force";
+        }
         status += "_on";
       }
       if (gpu_feature_data.name == "opengl" ||
@@ -431,13 +432,12 @@
   const base::CommandLine& command_line =
       *base::CommandLine::ForCurrentProcess();
 
-  if (command_line.HasSwitch(blink::switches::kNumRasterThreads)) {
+  if (command_line.HasSwitch(cc::switches::kNumRasterThreads)) {
     std::string string_value =
-        command_line.GetSwitchValueASCII(blink::switches::kNumRasterThreads);
+        command_line.GetSwitchValueASCII(cc::switches::kNumRasterThreads);
     if (!base::StringToInt(string_value, &num_raster_threads)) {
       DLOG(WARNING) << "Failed to parse switch "
-                    << blink::switches::kNumRasterThreads << ": "
-                    << string_value;
+                    << cc::switches::kNumRasterThreads << ": " << string_value;
     }
   }
 
diff --git a/content/browser/indexed_db/indexed_db_context_impl.cc b/content/browser/indexed_db/indexed_db_context_impl.cc
index 068ca95..84fc60d 100644
--- a/content/browser/indexed_db/indexed_db_context_impl.cc
+++ b/content/browser/indexed_db/indexed_db_context_impl.cc
@@ -1021,7 +1021,8 @@
     auto delete_bucket = origins_to_purge_on_shutdown_.find(
                              bucket_locator.storage_key.origin()) !=
                          origins_to_purge_on_shutdown_.end();
-    if (!delete_bucket) {
+
+    if (!delete_bucket && bucket_locator.storage_key.IsThirdPartyContext()) {
       auto& bucket_site = bucket_locator.storage_key.top_level_site();
       for (const auto& origin_to_purge : origins_to_purge_on_shutdown_) {
         if (net::SchemefulSite(origin_to_purge) == bucket_site) {
diff --git a/content/browser/indexed_db/indexed_db_unittest.cc b/content/browser/indexed_db/indexed_db_unittest.cc
index 204c05d8..ae95398a 100644
--- a/content/browser/indexed_db/indexed_db_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_unittest.cc
@@ -361,19 +361,10 @@
   base::RunLoop().RunUntilIdle();
 
   EXPECT_TRUE(base::DirectoryExists(normal_path_first_party));
-  // TODO(https://crbug.com/1429467): This directory shouldn't be deleted
-  // because it's a first-party context, which we only want to delete data for
-  // based on origin.
-  EXPECT_FALSE(base::DirectoryExists(session_only_path_first_party));
+  EXPECT_TRUE(base::DirectoryExists(session_only_path_first_party));
   EXPECT_FALSE(base::DirectoryExists(session_only_subdomain_path_first_party));
   EXPECT_TRUE(base::DirectoryExists(normal_path_third_party));
-  // TODO(https://crbug.com/1429467): Delete this conditional and always
-  // EXPECT_TRUE once this issue is fixed.
-  if (IsThirdPartyStoragePartitioningEnabled()) {
-    EXPECT_TRUE(base::DirectoryExists(session_only_path_third_party));
-  } else {
-    EXPECT_FALSE(base::DirectoryExists(session_only_path_third_party));
-  }
+  EXPECT_TRUE(base::DirectoryExists(session_only_path_third_party));
   EXPECT_FALSE(base::DirectoryExists(session_only_subdomain_path_third_party));
   EXPECT_TRUE(base::DirectoryExists(inverted_normal_path_third_party));
   // When storage partitioning is enabled these will be deleted because they
diff --git a/content/browser/per_web_ui_browser_interface_broker.cc b/content/browser/per_web_ui_browser_interface_broker.cc
index d85e17e..dd32a42 100644
--- a/content/browser/per_web_ui_browser_interface_broker.cc
+++ b/content/browser/per_web_ui_browser_interface_broker.cc
@@ -15,7 +15,7 @@
 namespace {
 void ShutdownWebUIRenderer(WebUIController& controller) {
   auto* webui_impl = static_cast<WebUIImpl*>(controller.web_ui());
-  webui_impl->frame_host()->GetProcess()->ShutdownForBadMessage(
+  webui_impl->GetRenderFrameHost()->GetProcess()->ShutdownForBadMessage(
       RenderProcessHost::CrashReportMode::GENERATE_CRASH_DUMP);
 }
 }  // namespace
diff --git a/content/browser/preloading/prefetch/prefetch_url_loader_interceptor_unittest.cc b/content/browser/preloading/prefetch/prefetch_url_loader_interceptor_unittest.cc
index 4c490cb..e6c3cfea 100644
--- a/content/browser/preloading/prefetch/prefetch_url_loader_interceptor_unittest.cc
+++ b/content/browser/preloading/prefetch/prefetch_url_loader_interceptor_unittest.cc
@@ -24,6 +24,7 @@
 #include "content/browser/preloading/prefetch/prefetch_type.h"
 #include "content/browser/preloading/prefetch/prefetch_url_loader_helper.h"
 #include "content/browser/preloading/preloading.h"
+#include "content/browser/preloading/preloading_config.h"
 #include "content/browser/preloading/preloading_data_impl.h"
 #include "content/browser/renderer_host/frame_tree_node.h"
 #include "content/browser/renderer_host/navigation_request.h"
@@ -254,10 +255,13 @@
         std::make_unique<base::ScopedMockElapsedTimersForTest>();
 
     scoped_feature_list_.InitAndDisableFeature(::features::kPreloadingConfig);
+    PreloadingConfig::GetInstance().ParseConfig();
   }
 
   void TearDown() override {
     interceptor_.release();
+    scoped_feature_list_.Reset();
+    PreloadingConfig::GetInstance().ParseConfig();
 
     RenderViewHostTestHarness::TearDown();
   }
diff --git a/content/browser/preloading/speculation_rules/speculation_host_impl_unittest.cc b/content/browser/preloading/speculation_rules/speculation_host_impl_unittest.cc
index 84bc0fc9..0ca688b02 100644
--- a/content/browser/preloading/speculation_rules/speculation_host_impl_unittest.cc
+++ b/content/browser/preloading/speculation_rules/speculation_host_impl_unittest.cc
@@ -45,6 +45,7 @@
   void TearDown() override {
     web_contents_.reset();
     browser_context_.reset();
+    mojo::SetDefaultProcessErrorHandler(base::NullCallback());
     RenderViewHostImplTestHarness::TearDown();
   }
 
diff --git a/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc b/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc
index e5bed3fe..ca78b76a 100644
--- a/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc
+++ b/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc
@@ -790,7 +790,7 @@
                                ui::EventTimeForNow());
   followup_event.touches_length = 1;
   followup_event.touches[0].id = 0;
-  followup_event.unique_touch_event_id = 100;
+  followup_event.unique_touch_event_id = ui::GetNextTouchEventId();
   followup_event.touches[0].state = WebTouchPoint::State::kStateMoved;
   SetFollowupEvent(followup_event);
   SetSyncAckResult(blink::mojom::InputEventResultState::kConsumed);
@@ -801,7 +801,8 @@
   EXPECT_EQ(0U, queued_event_count());
   EXPECT_EQ(1U, GetAndResetSentEventCount());
   EXPECT_EQ(3U, GetAndResetAckedEventCount());
-  EXPECT_EQ(100U, acked_event().unique_touch_event_id);
+  EXPECT_EQ(followup_event.unique_touch_event_id,
+            acked_event().unique_touch_event_id);
 }
 
 // Tests that followup events triggered by an immediate ack from
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
index 2c42f43..bf4edfb 100644
--- a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
+++ b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
@@ -51,8 +51,9 @@
 
   RenderFrameHost* render_frame_host =
       RenderFrameHost::FromID(render_process_id, render_frame_id);
-  if (render_frame_host && render_frame_host->IsRenderFrameLive())
+  if (render_frame_host && render_frame_host->IsRenderFrameLive()) {
     render_frame_host->GetRemoteInterfaces()->GetInterface(std::move(receiver));
+  }
 }
 
 std::unique_ptr<MediaStreamWebContentsObserver, BrowserThread::DeleteOnUIThread>
@@ -345,8 +346,9 @@
 
   RenderFrameHostImpl* render_frame_host =
       RenderFrameHostImpl::FromID(render_process_id, render_frame_id);
-  if (!render_frame_host)
+  if (!render_frame_host) {
     return false;
+  }
   ContentBrowserClient* browser_client = GetContentClient()->browser();
   return browser_client->IsGetDisplayMediaSetSelectAllScreensAllowed(
       render_frame_host->GetBrowserContext(),
@@ -377,8 +379,9 @@
 MediaStreamDispatcherHost::GetMediaStreamDeviceObserver() {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
-  if (media_stream_device_observer_)
+  if (media_stream_device_observer_) {
     return media_stream_device_observer_;
+  }
 
   auto dispatcher_receiver =
       media_stream_device_observer_.BindNewPipeAndPassReceiver();
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
index 07a63a6..61ca5243c 100644
--- a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
+++ b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
@@ -260,12 +260,14 @@
 
   void OnDeviceStoppedInternal(const std::string& label,
                                const blink::MediaStreamDevice& device) {
-    if (blink::IsVideoInputMediaType(device.type))
+    if (blink::IsVideoInputMediaType(device.type)) {
       EXPECT_TRUE(device.IsSameDevice(
           stream_devices_set_->stream_devices[0]->video_device.value()));
-    if (blink::IsAudioInputMediaType(device.type))
+    }
+    if (blink::IsAudioInputMediaType(device.type)) {
       EXPECT_TRUE(device.IsSameDevice(
           stream_devices_set_->stream_devices[0]->audio_device.value()));
+    }
 
     OnDeviceStopSuccess();
   }
@@ -407,8 +409,9 @@
     std::unique_ptr<MockMediaStreamUIProxy> fake_ui =
         std::make_unique<MockMediaStreamUIProxy>();
 
-    if (expect_started)
+    if (expect_started) {
       EXPECT_CALL(*fake_ui, MockOnStarted(_));
+    }
     return fake_ui;
   }
 
@@ -481,19 +484,22 @@
 
   bool DoesContainRawIds(
       const absl::optional<blink::MediaStreamDevice>& optional_device) {
-    if (!optional_device.has_value())
+    if (!optional_device.has_value()) {
       return false;
+    }
     const blink::MediaStreamDevice& device = optional_device.value();
     if (device.id != media::AudioDeviceDescription::kDefaultDeviceId &&
         device.id != media::AudioDeviceDescription::kCommunicationsDeviceId) {
       for (const auto& audio_device : audio_device_descriptions_) {
-        if (audio_device.unique_id == device.id)
+        if (audio_device.unique_id == device.id) {
           return true;
+        }
       }
     }
     for (const std::string& device_id : stub_video_device_ids_) {
-      if (device_id == device.id)
+      if (device_id == device.id) {
         return true;
+      }
     }
     return false;
   }
@@ -501,8 +507,9 @@
   bool DoesEveryDeviceMapToRawId(
       const absl::optional<blink::MediaStreamDevice>& optional_device,
       const url::Origin& origin) {
-    if (!optional_device.has_value())
+    if (!optional_device.has_value()) {
       return true;
+    }
     const blink::MediaStreamDevice& device = optional_device.value();
     if (device.type != blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE &&
         device.type != blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE) {
@@ -1153,8 +1160,9 @@
 
   // Create first group of streams.
   size_t generated_streams = 3;
-  for (size_t i = 0; i < generated_streams; ++i)
+  for (size_t i = 0; i < generated_streams; ++i) {
     GenerateStreamAndWaitForResult(kPageRequestId + i, controls, expectation);
+  }
 
   media_stream_manager_->CancelAllRequests(kProcessId, kRenderId, kRequesterId);
   base::RunLoop().RunUntilIdle();
diff --git a/content/browser/renderer_host/navigation_controller_history_intervention_browsertest.cc b/content/browser/renderer_host/navigation_controller_history_intervention_browsertest.cc
new file mode 100644
index 0000000..20f6fda4
--- /dev/null
+++ b/content/browser/renderer_host/navigation_controller_history_intervention_browsertest.cc
@@ -0,0 +1,1425 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/test/scoped_feature_list.h"
+#include "content/browser/renderer_host/frame_tree.h"
+#include "content/browser/renderer_host/navigation_controller_impl.h"
+#include "content/browser/renderer_host/navigation_request.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/common/features.h"
+#include "content/public/test/back_forward_cache_util.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/test_navigation_observer.h"
+#include "content/shell/browser/shell.h"
+#include "content/shell/common/shell_switches.h"
+#include "content/test/content_browser_test_utils_internal.h"
+#include "content/test/render_document_feature.h"
+#include "net/dns/mock_host_resolver.h"
+
+namespace content {
+
+namespace {
+
+// Does a renderer-initiated location.replace navigation to |url|, replacing the
+// current entry.
+bool RendererLocationReplace(Shell* shell, const GURL& url) {
+  WebContents* web_contents = shell->web_contents();
+  WaitForLoadStop(web_contents);
+  TestNavigationManager navigation_manager(web_contents, url);
+  const GURL& current_url =
+      web_contents->GetPrimaryMainFrame()->GetLastCommittedURL();
+  // Execute script in an isolated world to avoid causing a Trusted Types
+  // violation due to eval.
+  EXPECT_TRUE(ExecJs(shell, JsReplace("window.location.replace($1)", url),
+                     EXECUTE_SCRIPT_DEFAULT_OPTIONS, /*world_id=*/1));
+  // Observe pending entry if it's not a same-document navigation. We can't
+  // observe same-document navigations because it might finish in the renderer,
+  // only telling the browser side at the end.
+  if (!current_url.EqualsIgnoringRef(url)) {
+    EXPECT_TRUE(navigation_manager.WaitForRequestStart());
+    EXPECT_TRUE(
+        NavigationRequest::From(navigation_manager.GetNavigationHandle())
+            ->common_params()
+            .should_replace_current_entry);
+  }
+  EXPECT_TRUE(navigation_manager.WaitForNavigationFinished());
+  if (!IsLastCommittedEntryOfPageType(web_contents, PAGE_TYPE_NORMAL)) {
+    return false;
+  }
+  return web_contents->GetLastCommittedURL() == url;
+}
+
+}  // namespace
+
+class NavigationControllerHistoryInterventionBrowserTest
+    : public ContentBrowserTest,
+      public ::testing::WithParamInterface<
+          std::tuple<std::string /* render_document_level */,
+                     bool /* enable_back_forward_cache*/>> {
+ public:
+  NavigationControllerHistoryInterventionBrowserTest() {
+    feature_list_.InitWithFeaturesAndParameters(
+        {{kQueueNavigationsWhileWaitingForCommit, {{"level", "full"}}}}, {});
+    InitAndEnableRenderDocumentFeature(&feature_list_for_render_document_,
+                                       std::get<0>(GetParam()));
+    InitBackForwardCacheFeature(&feature_list_for_back_forward_cache_,
+                                std::get<1>(GetParam()));
+  }
+
+  // Provides meaningful param names instead of /0, /1, ...
+  static std::string DescribeParams(
+      const testing::TestParamInfo<ParamType>& info) {
+    auto [render_document_level, enable_back_forward_cache] = info.param;
+    return base::StringPrintf(
+        "%s_%s",
+        GetRenderDocumentLevelNameForTestParams(render_document_level).c_str(),
+        enable_back_forward_cache ? "BFCacheEnabled" : "BFCacheDisabled");
+  }
+
+ protected:
+  void SetUpOnMainThread() override {
+    host_resolver()->AddRule("*", "127.0.0.1");
+    content::SetupCrossSiteRedirector(embedded_test_server());
+    ASSERT_TRUE(embedded_test_server()->Start());
+  }
+
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    ContentBrowserTest::SetUpCommandLine(command_line);
+    base::CommandLine::ForCurrentProcess()->AppendSwitch(
+        switches::kExposeInternalsForTesting);
+  }
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
+  base::test::ScopedFeatureList feature_list_for_render_document_;
+  base::test::ScopedFeatureList feature_list_for_back_forward_cache_;
+};
+
+// Tests that the navigation entry is marked as skippable on back/forward button
+// if it does a renderer initiated navigation without ever getting a user
+// activation.
+IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
+                       NoUserActivationSetSkipOnBackForward) {
+  GURL non_skippable_url(
+      embedded_test_server()->GetURL("/frame_tree/top.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
+
+  GURL skippable_url(embedded_test_server()->GetURL("/title1.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
+
+  // It is safe to obtain the root frame tree node here, as it doesn't change.
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetPrimaryFrameTree()
+                            .root();
+
+  EXPECT_FALSE(root->HasStickyUserActivation());
+  EXPECT_FALSE(root->HasTransientUserActivation());
+
+  // Navigate to a new same-site document from the renderer without a user
+  // gesture.
+  GURL redirected_url(embedded_test_server()->GetURL("/title2.html"));
+  EXPECT_TRUE(
+      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
+
+  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
+      shell()->web_contents()->GetController());
+  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
+
+  // Last entry should have been marked as skippable.
+  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(
+      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
+
+  EXPECT_TRUE(controller.CanGoBack());
+  // Attempt to go back or forward to the skippable entry should log the
+  // corresponding histogram and skip the corresponding entry.
+  TestNavigationObserver back_load_observer(shell()->web_contents());
+  controller.GoBack();
+  back_load_observer.Wait();
+  EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL());
+  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
+}
+
+// Same as the above test except the navigation is cross-site in this case.
+// Tests that the navigation entry is marked as skippable on back/forward button
+// if it does a renderer initiated cross-site navigation without ever getting a
+// user activation.
+IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
+                       NoUserActivationSetSkipOnBackForwardCrossSite) {
+  GURL non_skippable_url(
+      embedded_test_server()->GetURL("/frame_tree/top.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
+
+  GURL skippable_url(embedded_test_server()->GetURL("/title1.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
+
+  // It is safe to obtain the root frame tree node here, as it doesn't change.
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetPrimaryFrameTree()
+                            .root();
+
+  EXPECT_FALSE(root->HasStickyUserActivation());
+  EXPECT_FALSE(root->HasTransientUserActivation());
+
+  // Navigate to a new cross-site document from the renderer with a user
+  // gesture.
+  GURL redirected_url(
+      embedded_test_server()->GetURL("foo.com", "/title1.html"));
+  EXPECT_TRUE(
+      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
+
+  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
+      shell()->web_contents()->GetController());
+  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
+
+  // Last entry should have been marked as skippable.
+  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(
+      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
+
+  EXPECT_TRUE(controller.CanGoBack());
+  // Attempt to go back or forward to the skippable entry should log the
+  // corresponding histogram and skip the corresponding entry.
+  TestNavigationObserver back_load_observer(shell()->web_contents());
+  controller.GoBack();
+  back_load_observer.Wait();
+  EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL());
+  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
+}
+
+// Tests that when a navigation entry is not marked as skippable the first time
+// it redirects because of user activation, that entry will be marked skippable
+// if it does another redirect without user activation after the user has come
+// back to that document again. This implies that a single user activation does
+// not mean that the user can be infintely trapped.
+IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
+                       NoUserActivationAfterReturningSetsSkippable) {
+  GURL non_skippable_url(
+      embedded_test_server()->GetURL("/frame_tree/top.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
+
+  GURL initially_non_skippable_url(
+      embedded_test_server()->GetURL("/title1.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), initially_non_skippable_url));
+
+  // It is safe to obtain the root frame tree node here, as it doesn't change.
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetPrimaryFrameTree()
+                            .root();
+
+  EXPECT_FALSE(root->HasStickyUserActivation());
+  EXPECT_FALSE(root->HasTransientUserActivation());
+
+  // Get a user activation and navigate to a new same-site document from the
+  // renderer with a user gesture.
+  GURL redirected_url(embedded_test_server()->GetURL("/title2.html"));
+  EXPECT_TRUE(NavigateToURLFromRenderer(shell(), redirected_url));
+
+  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
+      shell()->web_contents()->GetController());
+  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
+
+  // Last entry should have not been marked as skippable.
+  EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(
+      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
+
+  // Navigate back to the earlier document's entry.
+  {
+    TestNavigationObserver back_load_observer(shell()->web_contents());
+    controller.GoBack();
+    back_load_observer.Wait();
+  }
+  EXPECT_EQ(initially_non_skippable_url,
+            controller.GetLastCommittedEntry()->GetURL());
+  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
+
+  // Navigate to a new same-site document from the renderer without a user
+  // gesture.
+  EXPECT_TRUE(
+      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
+
+  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
+
+  // Last entry should have been marked as skippable due to the lack of
+  // activation on this visit, despite not being marked skippable last time.
+  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(
+      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
+
+  // Going back now should skip the entry at [1].
+  ASSERT_TRUE(controller.CanGoBack());
+  {
+    TestNavigationObserver back_load_observer(shell()->web_contents());
+    controller.GoBack();
+    back_load_observer.Wait();
+  }
+  EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL());
+  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
+}
+
+// Tests that the navigation entry is marked as skippable on back button if it
+// does a renderer initiated navigation without ever getting a user activation.
+// Also tests this for an entry added using history.pushState.
+IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
+                       NoUserActivationSetSkippableMultipleGoBack) {
+  GURL skippable_url(embedded_test_server()->GetURL("/frame_tree/top.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
+
+  // It is safe to obtain the root frame tree node here, as it doesn't change.
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetPrimaryFrameTree()
+                            .root();
+
+  EXPECT_FALSE(root->HasStickyUserActivation());
+  EXPECT_FALSE(root->HasTransientUserActivation());
+
+  // Navigate to a new same-site document from the renderer without a user
+  // gesture.
+  GURL redirected_url(embedded_test_server()->GetURL("/title1.html"));
+  EXPECT_TRUE(
+      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
+
+  // Use the pushState API to add another entry without user gesture.
+  GURL push_state_url(embedded_test_server()->GetURL("/title2.html"));
+  std::string script("history.pushState('', '','" + push_state_url.spec() +
+                     "');");
+  EXPECT_TRUE(
+      ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE));
+
+  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
+      shell()->web_contents()->GetController());
+  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
+
+  // Last 2 entries should have been marked as skippable.
+  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
+  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(
+      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
+
+  // CanGoBack should return false since all previous entries are skippable.
+  EXPECT_FALSE(controller.CanGoBack());
+}
+
+// Same as above but tests the metrics on going forward.
+IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
+                       NoUserActivationSetSkippableMultipleGoForward) {
+  GURL skippable_url(embedded_test_server()->GetURL("/frame_tree/top.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
+
+  // It is safe to obtain the root frame tree node here, as it doesn't change.
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetPrimaryFrameTree()
+                            .root();
+
+  EXPECT_FALSE(root->HasStickyUserActivation());
+  EXPECT_FALSE(root->HasTransientUserActivation());
+
+  // Navigate to a new same-site document from the renderer without a user
+  // gesture.
+  GURL redirected_url(embedded_test_server()->GetURL("/title1.html"));
+  EXPECT_TRUE(
+      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
+
+  // Use the pushState API to add another entry without user gesture.
+  GURL push_state_url(embedded_test_server()->GetURL("/title2.html"));
+  std::string script("history.pushState('', '','" + push_state_url.spec() +
+                     "');");
+  EXPECT_TRUE(
+      ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE));
+
+  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
+      shell()->web_contents()->GetController());
+  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
+
+  // Last 2 entries should have been marked as skippable.
+  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
+  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(
+      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
+}
+
+// Tests that if an entry is marked as skippable, it will not be reset if there
+// is a navigation to this entry again (crbug.com/112129).
+IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
+                       DoNotResetSkipOnBackForward) {
+  GURL main_url(embedded_test_server()->GetURL("/frame_tree/top.html"));
+
+  EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+  // It is safe to obtain the root frame tree node here, as it doesn't change.
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetPrimaryFrameTree()
+                            .root();
+
+  EXPECT_FALSE(root->HasStickyUserActivation());
+  EXPECT_FALSE(root->HasTransientUserActivation());
+
+  // Navigate to a new same-site document from the renderer without a user
+  // gesture.
+  GURL url(embedded_test_server()->GetURL("/title1.html"));
+  EXPECT_TRUE(NavigateToURLFromRendererWithoutUserGesture(shell(), url));
+
+  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
+      shell()->web_contents()->GetController());
+  EXPECT_EQ(1, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
+
+  // Last entry should have been marked as skippable.
+  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(
+      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
+
+  // Go back to the last entry.
+  TestNavigationObserver back_nav_load_observer(shell()->web_contents());
+  controller.GoToIndex(0);
+  back_nav_load_observer.Wait();
+
+  // Going back again to an entry should not reset its skippable flag.
+  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
+
+  // Navigating away from this with a browser initiated navigation should log a
+  // histogram with skippable as true.
+  GURL url1(embedded_test_server()->GetURL("/title2.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), url1));
+}
+
+// Tests that if an entry is marked as skippable, it will not be reset if there
+// is a navigation to this entry again (crbug.com/1121293) using history.back/
+// forward.
+IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
+                       DoNotResetSkipOnHistoryBackAPI) {
+  GURL main_url(embedded_test_server()->GetURL("/frame_tree/top.html"));
+
+  EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+  // It is safe to obtain the root frame tree node here, as it doesn't change.
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetPrimaryFrameTree()
+                            .root();
+
+  EXPECT_FALSE(root->HasStickyUserActivation());
+  EXPECT_FALSE(root->HasTransientUserActivation());
+
+  // Navigate to a new same-site document from the renderer without a user
+  // gesture.
+  GURL url(embedded_test_server()->GetURL("/title1.html"));
+  EXPECT_TRUE(NavigateToURLFromRendererWithoutUserGesture(shell(), url));
+
+  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
+      shell()->web_contents()->GetController());
+  EXPECT_EQ(1, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
+
+  // Last entry should have been marked as skippable.
+  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(
+      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
+
+  // Go back to the last entry using history.back.
+  EXPECT_TRUE(
+      ExecJs(shell(), "history.back();", EXECUTE_SCRIPT_NO_USER_GESTURE));
+  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+
+  // Going back again to an entry should not reset its skippable flag.
+  EXPECT_TRUE(
+      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
+  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
+}
+
+// Tests that if a navigation entry is marked as skippable due to pushState then
+// the flag should be reset if there is a user gesture on this document. All of
+// the adjacent entries belonging to the same document will have their skippable
+// bits reset.
+IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
+                       OnUserGestureResetSameDocumentEntriesSkipFlag) {
+  GURL skippable_url(embedded_test_server()->GetURL("/frame_tree/top.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
+
+  // It is safe to obtain the root frame tree node here, as it doesn't change.
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetPrimaryFrameTree()
+                            .root();
+
+  EXPECT_FALSE(root->HasStickyUserActivation());
+  EXPECT_FALSE(root->HasTransientUserActivation());
+
+  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
+      shell()->web_contents()->GetController());
+
+  // Redirect to another page without a user gesture.
+  GURL redirected_url(embedded_test_server()->GetURL("/empty.html"));
+  EXPECT_TRUE(
+      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
+  // Last entry should have been marked as skippable.
+  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
+
+  // Use the pushState API to add another entry without user gesture.
+  GURL push_state_url1(embedded_test_server()->GetURL("/title1.html"));
+  std::string script("history.pushState('', '','" + push_state_url1.spec() +
+                     "');");
+  EXPECT_TRUE(
+      ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE));
+
+  // Use the pushState API to add another entry without user gesture.
+  GURL push_state_url2(embedded_test_server()->GetURL("/title2.html"));
+  script = "history.pushState('', '','" + push_state_url2.spec() + "');";
+  EXPECT_TRUE(
+      ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE));
+
+  EXPECT_EQ(3, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(3, controller.GetLastCommittedEntryIndex());
+
+  // We now have
+  // [skippable_url(skip), redirected_url(skip), push_state_url1(skip),
+  // push_state_url2*]
+  // Last 2 entries should have been marked as skippable.
+  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
+  EXPECT_TRUE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(
+      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
+
+  EXPECT_EQ(skippable_url, controller.GetEntryAtIndex(0)->GetURL());
+  EXPECT_EQ(redirected_url, controller.GetEntryAtIndex(1)->GetURL());
+  EXPECT_EQ(push_state_url1, controller.GetEntryAtIndex(2)->GetURL());
+  EXPECT_EQ(push_state_url2, controller.GetEntryAtIndex(3)->GetURL());
+
+  // Do another pushState so push_state_url2's entry also becomes skippable.
+  GURL push_state_url3(embedded_test_server()->GetURL("/title3.html"));
+  script = "history.pushState('', '','" + push_state_url3.spec() + "');";
+  EXPECT_TRUE(
+      ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE));
+  EXPECT_TRUE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui());
+  // We now have
+  // [skippable_url(skip), redirected_url(skip), push_state_url1(skip),
+  // push_state_url2(skip), push_state_url3*]
+
+  // Go to index 2.
+  TestNavigationObserver load_observer(shell()->web_contents());
+  controller.GoToIndex(2);
+  load_observer.Wait();
+  EXPECT_EQ(push_state_url1, controller.GetLastCommittedEntry()->GetURL());
+
+  // We now have (Before user gesture)
+  // [skippable_url(skip), redirected_url(skip), push_state_url1(skip)*,
+  // push_state_url2(skip), push_state_url3]
+  // Note the entry at index 2 retains its skippable flag.
+  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
+  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
+  EXPECT_TRUE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui());
+  EXPECT_TRUE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui());
+
+  // Simulate a user gesture. ExecuteScript internally also sends a user
+  // gesture.
+  script = "a=5";
+  EXPECT_TRUE(content::ExecJs(shell()->web_contents(), script));
+
+  // We now have (After user gesture)
+  // [skippable_url(skip), redirected_url, push_state_url1*, push_state_url2,
+  // push_state_url3]
+  // All the navigations that refer to the same document should have their
+  // skippable bit reset.
+  EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui());
+  // The first entry is not the same document and its bit should not be reset.
+  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
+
+  // goBack should now navigate to entry at index 1.
+  TestNavigationObserver back_load_observer(shell()->web_contents());
+  controller.GoBack();
+  back_load_observer.Wait();
+  EXPECT_EQ(redirected_url, controller.GetLastCommittedEntry()->GetURL());
+
+  // Do another pushState without user gesture.
+  GURL push_state_url4(embedded_test_server()->GetURL("/title3.html"));
+  script = "history.pushState('', '','" + push_state_url3.spec() + "');";
+  EXPECT_TRUE(
+      ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE));
+  // We now have
+  // [skippable_url(skip), redirected_url, push_state_url4*]
+  EXPECT_EQ(3, controller.GetEntryCount());
+  EXPECT_EQ(skippable_url, controller.GetEntryAtIndex(0)->GetURL());
+  EXPECT_EQ(redirected_url, controller.GetEntryAtIndex(1)->GetURL());
+  EXPECT_EQ(push_state_url4, controller.GetEntryAtIndex(2)->GetURL());
+  // The skippable flag will still be unset since this page has seen a user
+  // gesture once.
+  EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
+}
+
+class NavigationControllerDebugHistoryInterventionNoUserActivation
+    : public NavigationControllerHistoryInterventionBrowserTest {
+ protected:
+  void SetUp() override {
+    feature_list_.InitAndEnableFeature(
+        features::kDebugHistoryInterventionNoUserActivation);
+    NavigationControllerHistoryInterventionBrowserTest::SetUp();
+  }
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
+};
+
+// Tests that if a navigation entry is marked as skippable due to pushState then
+// the flag is not reset even if there is a user gesture on this document, when
+// the debug flag is enabled. This is to check the case where there wasn't
+// actually a user gesture but one is being reported somehow.
+// (See crbug.com/1201355)
+IN_PROC_BROWSER_TEST_P(
+    NavigationControllerDebugHistoryInterventionNoUserActivation,
+    OnUserGestureDoNotResetSameDocumentEntriesSkipFlag) {
+  GURL skippable_url(embedded_test_server()->GetURL("/frame_tree/top.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
+
+  // It is safe to obtain the root frame tree node here, as it doesn't change.
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetPrimaryFrameTree()
+                            .root();
+
+  EXPECT_FALSE(root->HasStickyUserActivation());
+  EXPECT_FALSE(root->HasTransientUserActivation());
+
+  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
+      shell()->web_contents()->GetController());
+
+  // Redirect to another page without a user gesture.
+  GURL redirected_url(embedded_test_server()->GetURL("/empty.html"));
+  EXPECT_TRUE(
+      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
+  // Last entry should have been marked as skippable.
+  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
+
+  // Use the pushState API to add another entry without user gesture.
+  GURL push_state_url1(embedded_test_server()->GetURL("/title1.html"));
+  std::string script("history.pushState('', '','" + push_state_url1.spec() +
+                     "');");
+  EXPECT_TRUE(
+      ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE));
+
+  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
+
+  // We now have
+  // [skippable_url(skip), redirected_url(skip), push_state_url1*]
+  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(
+      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
+
+  EXPECT_EQ(skippable_url, controller.GetEntryAtIndex(0)->GetURL());
+  EXPECT_EQ(redirected_url, controller.GetEntryAtIndex(1)->GetURL());
+  EXPECT_EQ(push_state_url1, controller.GetEntryAtIndex(2)->GetURL());
+
+  // Simulate a user gesture. ExecuteScript internally also sends a user
+  // gesture. The skippable bit for [1] should not have changed because of the
+  // DebugHistoryInterventionNoUserActivation flag.
+  script = "a=5";
+  EXPECT_TRUE(content::ExecJs(shell()->web_contents(), script));
+
+  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
+  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
+}
+
+// Tests that if a navigation entry is marked as skippable due to redirect to a
+// new document then the flag should not be reset if there is a user gesture on
+// the new document.
+IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
+                       OnUserGestureDoNotResetDifferentDocumentEntrySkipFlag) {
+  GURL skippable_url(embedded_test_server()->GetURL("/frame_tree/top.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
+
+  // It is safe to obtain the root frame tree node here, as it doesn't change.
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetPrimaryFrameTree()
+                            .root();
+
+  EXPECT_FALSE(root->HasStickyUserActivation());
+  EXPECT_FALSE(root->HasTransientUserActivation());
+
+  // Navigate to a new same-site document from the renderer without a user
+  // gesture.
+  GURL redirected_url(embedded_test_server()->GetURL("/title1.html"));
+  EXPECT_TRUE(
+      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
+
+  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
+      shell()->web_contents()->GetController());
+  EXPECT_EQ(1, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
+
+  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(
+      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
+
+  // Simulate a user gesture.
+  root->UpdateUserActivationState(
+      blink::mojom::UserActivationUpdateType::kNotifyActivation,
+      blink::mojom::UserActivationNotificationType::kTest);
+
+  // Since the last navigations refer to a different document, a user gesture
+  // here should not reset the skippable bit in the previous entries.
+  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
+}
+
+// Tests that the navigation entry is not marked as skippable on back/forward
+// button if it does a renderer initiated navigation after getting a user
+// activation.
+IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
+                       UserActivationDoNotSkipOnBackForward) {
+  GURL non_skippable_url(
+      embedded_test_server()->GetURL("/frame_tree/top.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
+
+  // It is safe to obtain the root frame tree node here, as it doesn't change.
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetPrimaryFrameTree()
+                            .root();
+
+  EXPECT_FALSE(root->HasStickyUserActivation());
+  EXPECT_FALSE(root->HasTransientUserActivation());
+
+  // Navigate to a new same-site document from the renderer.
+  // Note that NavigateToURLFromRenderer also simulates a user gesture.
+  GURL user_gesture_redirected_url(
+      embedded_test_server()->GetURL("/title1.html"));
+  EXPECT_TRUE(NavigateToURLFromRenderer(shell(), user_gesture_redirected_url));
+
+  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
+      shell()->web_contents()->GetController());
+  EXPECT_EQ(1, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
+
+  // Last entry should not have been marked as skippable.
+  EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(
+      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
+
+  // Nothing should get skipped when back button is clicked.
+  TestNavigationObserver back_nav_load_observer(shell()->web_contents());
+  controller.GoBack();
+  back_nav_load_observer.Wait();
+  EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL());
+  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
+}
+
+// Tests that the navigation entry should not be marked as skippable on
+// back/forward button if it is navigated away using a browser initiated
+// navigation.
+IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
+                       BrowserInitiatedNavigationDoNotSkipOnBackForward) {
+  GURL non_skippable_url(
+      embedded_test_server()->GetURL("/frame_tree/top.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
+
+  // It is safe to obtain the root frame tree node here, as it doesn't change.
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetPrimaryFrameTree()
+                            .root();
+
+  EXPECT_FALSE(root->HasStickyUserActivation());
+  EXPECT_FALSE(root->HasTransientUserActivation());
+
+  GURL url(embedded_test_server()->GetURL("/title1.html"));
+
+  // Note that NavigateToURL simulates a browser initiated navigation.
+  EXPECT_TRUE(NavigateToURL(shell(), url));
+
+  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
+      shell()->web_contents()->GetController());
+  EXPECT_EQ(1, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
+
+  // Last entry should not have been marked as skippable.
+  EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(
+      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
+
+  // Nothing should get skipped when back button is clicked.
+  TestNavigationObserver back_nav_load_observer(shell()->web_contents());
+  controller.GoBack();
+  back_nav_load_observer.Wait();
+  EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL());
+  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
+}
+
+// Tests that the navigation entry that is marked as skippable on back/forward
+// button does not get skipped for history.back API calls.
+IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
+                       SetSkipOnBackDoNotSkipForHistoryBackAPI) {
+  GURL non_skippable_url(
+      embedded_test_server()->GetURL("/frame_tree/top.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
+
+  GURL skippable_url(embedded_test_server()->GetURL("/title1.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
+
+  // It is safe to obtain the root frame tree node here, as it doesn't change.
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetPrimaryFrameTree()
+                            .root();
+
+  EXPECT_FALSE(root->HasStickyUserActivation());
+  EXPECT_FALSE(root->HasTransientUserActivation());
+
+  // Navigate to a new same-site document from the renderer without a user
+  // gesture.
+  GURL redirected_url(embedded_test_server()->GetURL("/title2.html"));
+  EXPECT_TRUE(
+      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
+
+  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
+      shell()->web_contents()->GetController());
+  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
+
+  // Last entry should have been marked as skippable.
+  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(
+      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
+
+  // Attempt to go back to the skippable entry using the History API should
+  // not skip the corresponding entry.
+  TestNavigationObserver frame_observer(shell()->web_contents());
+  EXPECT_TRUE(ExecJs(root, "window.history.back()"));
+  frame_observer.Wait();
+
+  EXPECT_EQ(skippable_url, controller.GetLastCommittedEntry()->GetURL());
+  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
+}
+
+#if BUILDFLAG(IS_ANDROID)
+// Test GoToOffset with enable history intervention.
+IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
+                       GoToOffsetWithSkippingEnableHistoryIntervention) {
+  base::HistogramTester histograms;
+  GURL non_skippable_url(
+      embedded_test_server()->GetURL("/frame_tree/top.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
+
+  GURL skippable_url(embedded_test_server()->GetURL("/title1.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
+
+  // It is safe to obtain the root frame tree node here, as it doesn't change.
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetPrimaryFrameTree()
+                            .root();
+
+  EXPECT_FALSE(root->HasStickyUserActivation());
+  EXPECT_FALSE(root->HasTransientUserActivation());
+
+  // Navigate to a new same-site document from the renderer without a user
+  // gesture.
+  GURL redirected_url(embedded_test_server()->GetURL("/title2.html"));
+  EXPECT_TRUE(
+      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
+
+  GURL skippable_url2(embedded_test_server()->GetURL("/title3.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), skippable_url2));
+
+  EXPECT_FALSE(root->HasStickyUserActivation());
+  EXPECT_FALSE(root->HasTransientUserActivation());
+
+  // Navigate to a new same-site document from the renderer without a user
+  // gesture.
+  GURL redirected_url2(embedded_test_server()->GetURL("/title4.html"));
+  EXPECT_TRUE(
+      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url2));
+
+  // CanGoToOffset should visit the skippable entries while
+  // CanGoToOffsetWithSKipping will skip the skippable entries.
+  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
+      shell()->web_contents()->GetController());
+  EXPECT_TRUE(controller.CanGoToOffset(-3));
+  EXPECT_TRUE(controller.CanGoToOffset(-4));
+  EXPECT_FALSE(controller.CanGoToOffsetWithSkipping(-3));
+
+  TestNavigationObserver nav_observer(shell()->web_contents());
+  controller.GoToOffset(-4);
+  nav_observer.Wait();
+  EXPECT_EQ(0, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
+  EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL());
+}
+#endif  // BUILDFLAG(IS_ANDROID)
+
+// Tests that the navigation entry that is marked as skippable on back/forward
+// button does not get skipped for GoToOffset calls.
+// This covers actions in the following scenario:
+// [non_skippable_url, skippable_url, redirected_url, skippable_url2,
+// redirected_url2]
+IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
+                       SetSkipOnBackForwardDoNotSkipForGoToOffset) {
+  GURL non_skippable_url(
+      embedded_test_server()->GetURL("/frame_tree/top.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
+
+  GURL skippable_url(embedded_test_server()->GetURL("/title1.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
+
+  // It is safe to obtain the root frame tree node here, as it doesn't change.
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetPrimaryFrameTree()
+                            .root();
+
+  EXPECT_FALSE(root->HasStickyUserActivation());
+  EXPECT_FALSE(root->HasTransientUserActivation());
+
+  // Navigate to a new same-site document from the renderer without a user
+  // gesture.
+  GURL redirected_url(embedded_test_server()->GetURL("/title2.html"));
+  EXPECT_TRUE(
+      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
+
+  GURL skippable_url2(embedded_test_server()->GetURL("/title3.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), skippable_url2));
+
+  EXPECT_FALSE(root->HasStickyUserActivation());
+  EXPECT_FALSE(root->HasTransientUserActivation());
+
+  // Navigate to a new same-site document from the renderer without a user
+  // gesture.
+  GURL redirected_url2(embedded_test_server()->GetURL("/title4.html"));
+  EXPECT_TRUE(
+      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url2));
+
+  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
+      shell()->web_contents()->GetController());
+  EXPECT_EQ(4, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(4, controller.GetLastCommittedEntryIndex());
+
+  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui());
+  EXPECT_TRUE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui());
+
+  EXPECT_TRUE(controller.CanGoToOffset(-3));
+
+  // GoToOffset should visit the skippable entries.
+  TestNavigationObserver nav_observer1(shell()->web_contents());
+  controller.GoToOffset(-1);
+  nav_observer1.Wait();
+  EXPECT_EQ(3, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(3, controller.GetLastCommittedEntryIndex());
+  EXPECT_EQ(skippable_url2, controller.GetLastCommittedEntry()->GetURL());
+
+  TestNavigationObserver nav_observer2(shell()->web_contents());
+  controller.GoToOffset(1);
+  nav_observer2.Wait();
+  EXPECT_EQ(4, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(4, controller.GetLastCommittedEntryIndex());
+  EXPECT_EQ(redirected_url2, controller.GetLastCommittedEntry()->GetURL());
+
+  TestNavigationObserver nav_observer3(shell()->web_contents());
+  controller.GoToOffset(-4);
+  nav_observer3.Wait();
+  EXPECT_EQ(0, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
+  EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL());
+
+  EXPECT_TRUE(controller.CanGoToOffset(4));
+
+  TestNavigationObserver nav_observer4(shell()->web_contents());
+  controller.GoToOffset(4);
+  nav_observer4.Wait();
+  EXPECT_EQ(4, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(4, controller.GetLastCommittedEntryIndex());
+  EXPECT_EQ(redirected_url2, controller.GetLastCommittedEntry()->GetURL());
+}
+
+// Tests that the navigation entry that is marked as skippable on back/forward
+// button is skipped for GoToOffset calls.
+// This covers actions in the following scenario:
+// [non_skippable_url, skippable_url, redirected_url, skippable_url2,
+// redirected_url2]
+IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
+                       SetSkipOnBackForwardDoSkipForGoToOffsetWithSkipping) {
+#if BUILDFLAG(IS_ANDROID)
+  GURL non_skippable_url(
+      embedded_test_server()->GetURL("/frame_tree/top.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
+
+  GURL skippable_url(embedded_test_server()->GetURL("/title1.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
+
+  // It is safe to obtain the root frame tree node here, as it doesn't change.
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetPrimaryFrameTree()
+                            .root();
+
+  EXPECT_FALSE(root->HasStickyUserActivation());
+  EXPECT_FALSE(root->HasTransientUserActivation());
+
+  // Navigate to a new same-site document from the renderer without a user
+  // gesture.
+  GURL redirected_url(embedded_test_server()->GetURL("/title2.html"));
+  EXPECT_TRUE(
+      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
+
+  GURL skippable_url2(embedded_test_server()->GetURL("/title3.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), skippable_url2));
+
+  EXPECT_FALSE(root->HasStickyUserActivation());
+  EXPECT_FALSE(root->HasTransientUserActivation());
+
+  // Navigate to a new same-site document from the renderer without a user
+  // gesture.
+  GURL redirected_url2(embedded_test_server()->GetURL("/title4.html"));
+  EXPECT_TRUE(
+      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url2));
+
+  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
+      shell()->web_contents()->GetController());
+  EXPECT_EQ(4, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(4, controller.GetLastCommittedEntryIndex());
+
+  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui());
+  EXPECT_TRUE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui());
+
+  EXPECT_FALSE(controller.CanGoToOffsetWithSkipping(-3));
+  EXPECT_TRUE(controller.CanGoToOffsetWithSkipping(-2));
+
+  // GoToOffset should skip the skippable entries.
+  TestNavigationObserver nav_observer1(shell()->web_contents());
+  controller.GoToOffsetWithSkipping(-1);
+  nav_observer1.Wait();
+  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
+  EXPECT_EQ(redirected_url, controller.GetLastCommittedEntry()->GetURL());
+
+  TestNavigationObserver nav_observer2(shell()->web_contents());
+  controller.GoToOffsetWithSkipping(1);
+  nav_observer2.Wait();
+  EXPECT_EQ(4, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(4, controller.GetLastCommittedEntryIndex());
+  EXPECT_EQ(redirected_url2, controller.GetLastCommittedEntry()->GetURL());
+
+  TestNavigationObserver nav_observer3(shell()->web_contents());
+  controller.GoToOffsetWithSkipping(-2);
+  nav_observer3.Wait();
+  EXPECT_EQ(0, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
+  EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL());
+
+  EXPECT_FALSE(controller.CanGoToOffsetWithSkipping(3));
+  EXPECT_TRUE(controller.CanGoToOffsetWithSkipping(2));
+
+  TestNavigationObserver nav_observer4(shell()->web_contents());
+  controller.GoToOffsetWithSkipping(2);
+  nav_observer4.Wait();
+  EXPECT_EQ(4, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(4, controller.GetLastCommittedEntryIndex());
+  EXPECT_EQ(redirected_url2, controller.GetLastCommittedEntry()->GetURL());
+#endif  // BUILDFLAG(IS_ANDROID)
+}
+
+// Tests that the navigation entry that is marked as skippable on back/forward
+// button does not get skipped for history.forward API calls.
+IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
+                       SetSkipOnBackDoNotSkipForHistoryForwardAPI) {
+  GURL non_skippable_url(
+      embedded_test_server()->GetURL("/frame_tree/top.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
+
+  GURL skippable_url(embedded_test_server()->GetURL("/title1.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
+
+  // It is safe to obtain the root frame tree node here, as it doesn't change.
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetPrimaryFrameTree()
+                            .root();
+
+  EXPECT_FALSE(root->HasStickyUserActivation());
+  EXPECT_FALSE(root->HasTransientUserActivation());
+
+  // Navigate to a new same-site document from the renderer without a user
+  // gesture.
+  GURL redirected_url(embedded_test_server()->GetURL("/title2.html"));
+  EXPECT_TRUE(
+      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
+
+  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
+      shell()->web_contents()->GetController());
+  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
+
+  // Last entry should have been marked as skippable.
+  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(
+      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
+
+  TestNavigationObserver nav_observer1(shell()->web_contents());
+  controller.GoToIndex(0);
+  nav_observer1.Wait();
+  EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL());
+
+  // Attempt to go forward to the skippable entry using the History API should
+  // not skip the corresponding entry.
+  TestNavigationObserver nav_observer2(shell()->web_contents());
+  EXPECT_TRUE(ExecJs(root, "window.history.forward()"));
+  nav_observer2.Wait();
+
+  EXPECT_EQ(skippable_url, controller.GetLastCommittedEntry()->GetURL());
+  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
+}
+
+// Tests that the oldest navigation entry that is marked as skippable is the one
+// that is pruned if max entry count is reached.
+IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
+                       PruneOldestSkippableEntry) {
+  // Set the max entry count as 3.
+  NavigationControllerImpl::set_max_entry_count_for_testing(3);
+
+  GURL non_skippable_url(
+      embedded_test_server()->GetURL("/frame_tree/top.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
+
+  GURL skippable_url(embedded_test_server()->GetURL("/title1.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
+
+  // It is safe to obtain the root frame tree node here, as it doesn't change.
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetPrimaryFrameTree()
+                            .root();
+
+  EXPECT_FALSE(root->HasStickyUserActivation());
+  EXPECT_FALSE(root->HasTransientUserActivation());
+
+  // Navigate to a new same-site document from the renderer without a user
+  // gesture.
+  GURL redirected_url(embedded_test_server()->GetURL("/title2.html"));
+  EXPECT_TRUE(
+      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
+
+  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
+      shell()->web_contents()->GetController());
+  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
+  EXPECT_EQ(3, controller.GetEntryCount());
+  EXPECT_EQ(non_skippable_url, controller.GetEntryAtIndex(0)->GetURL());
+  EXPECT_EQ(skippable_url, controller.GetEntryAtIndex(1)->GetURL());
+  EXPECT_EQ(redirected_url, controller.GetEntryAtIndex(2)->GetURL());
+
+  // |skippable_url| entry should have been marked as skippable.
+  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(
+      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
+
+  // A new navigation should lead to |skippable_url| to be pruned.
+  GURL new_navigation_url(embedded_test_server()->GetURL("/title3.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), new_navigation_url));
+  // Should still have 3 entries.
+  EXPECT_EQ(3, controller.GetEntryCount());
+  EXPECT_EQ(non_skippable_url, controller.GetEntryAtIndex(0)->GetURL());
+  EXPECT_EQ(redirected_url, controller.GetEntryAtIndex(1)->GetURL());
+  EXPECT_EQ(new_navigation_url, controller.GetEntryAtIndex(2)->GetURL());
+}
+
+// Tests that we fallback to pruning the oldest entry if the last committed
+// entry is the oldest skippable navigation entry.
+IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
+                       PruneOldestWhenLastCommittedIsSkippable) {
+  // Set the max entry count as 2.
+  NavigationControllerImpl::set_max_entry_count_for_testing(2);
+
+  GURL non_skippable_url(
+      embedded_test_server()->GetURL("/frame_tree/top.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
+
+  GURL skippable_url(embedded_test_server()->GetURL("/title1.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
+
+  // It is safe to obtain the root frame tree node here, as it doesn't change.
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetPrimaryFrameTree()
+                            .root();
+
+  EXPECT_FALSE(root->HasStickyUserActivation());
+  EXPECT_FALSE(root->HasTransientUserActivation());
+
+  // Navigate to a new same-site document from the renderer without a user
+  // gesture. This will mark |skippable_url| as skippable but since that is also
+  // the last committed entry, it will not be pruned. Instead the oldest entry
+  // will be removed.
+  GURL redirected_url(embedded_test_server()->GetURL("/title2.html"));
+  EXPECT_TRUE(
+      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
+
+  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
+      shell()->web_contents()->GetController());
+  EXPECT_EQ(1, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
+  EXPECT_EQ(2, controller.GetEntryCount());
+  EXPECT_EQ(skippable_url, controller.GetEntryAtIndex(0)->GetURL());
+  EXPECT_EQ(redirected_url, controller.GetEntryAtIndex(1)->GetURL());
+
+  // |skippable_url| entry should have been marked as skippable.
+  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(
+      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
+}
+
+// Tests that the navigation entry is marked as skippable on back/forward
+// button if a subframe does a push state without ever getting a user
+// activation.
+IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
+                       NoUserActivationSetSkipOnBackForwardSubframe) {
+  GURL non_skippable_url(embedded_test_server()->GetURL("/title1.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
+
+  // It is safe to obtain the root frame tree node here, as it doesn't change.
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetPrimaryFrameTree()
+                            .root();
+
+  GURL skippable_url(
+      embedded_test_server()->GetURL("/frame_tree/page_with_one_frame.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
+
+  EXPECT_FALSE(root->HasStickyUserActivation());
+  EXPECT_FALSE(root->HasTransientUserActivation());
+
+  // Invoke pushstate from a subframe.
+  std::string script = "history.pushState({}, 'page 1', 'simple_page_1.html')";
+  EXPECT_TRUE(
+      ExecJs(root->child_at(0), script, EXECUTE_SCRIPT_NO_USER_GESTURE));
+
+  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
+      shell()->web_contents()->GetController());
+  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
+
+  EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
+  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui());
+
+  EXPECT_TRUE(controller.CanGoBack());
+
+  // Attempt to go back or forward to the skippable entry should log the
+  // corresponding histogram and skip the corresponding entry.
+  TestNavigationObserver back_load_observer(shell()->web_contents());
+  controller.GoBack();
+  back_load_observer.Wait();
+  EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL());
+  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
+
+  // Go forward to the 3rd entry.
+  TestNavigationObserver load_observer(shell()->web_contents());
+  controller.GoToIndex(2);
+  load_observer.Wait();
+
+  // A user gesture in the main frame now will lead to all same document
+  // entries to be marked as non-skippable.
+  root->UpdateUserActivationState(
+      blink::mojom::UserActivationUpdateType::kNotifyActivation,
+      blink::mojom::UserActivationNotificationType::kTest);
+  EXPECT_TRUE(root->HasStickyUserActivation());
+  EXPECT_TRUE(root->HasTransientUserActivation());
+  EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui());
+}
+
+// Tests that the navigation entry is not marked as skippable on back/forward
+// button if a subframe does a push state without ever getting a user
+// activation on itself but there was a user gesture on the main frame.
+IN_PROC_BROWSER_TEST_P(
+    NavigationControllerHistoryInterventionBrowserTest,
+    UserActivationMainFrameDoNotSetSkipOnBackForwardSubframe) {
+  GURL non_skippable_url(embedded_test_server()->GetURL("/title1.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
+
+  // It is safe to obtain the root frame tree node here, as it doesn't change.
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetPrimaryFrameTree()
+                            .root();
+
+  GURL url_with_frames(
+      embedded_test_server()->GetURL("/frame_tree/page_with_one_frame.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), url_with_frames));
+
+  EXPECT_FALSE(root->HasStickyUserActivation());
+  EXPECT_FALSE(root->HasTransientUserActivation());
+
+  // Simulate user gesture in the main frame. Subframes creating entries without
+  // user gesture will not lead to the last committed entry being marked as
+  // skippable.
+  root->UpdateUserActivationState(
+      blink::mojom::UserActivationUpdateType::kNotifyActivation,
+      blink::mojom::UserActivationNotificationType::kTest);
+  EXPECT_TRUE(root->HasStickyUserActivation());
+  EXPECT_TRUE(root->HasTransientUserActivation());
+
+  // Invoke pushstate from a subframe.
+  std::string script = "history.pushState({}, 'page 1', 'simple_page_1.html')";
+  EXPECT_TRUE(
+      ExecJs(root->child_at(0), script, EXECUTE_SCRIPT_NO_USER_GESTURE));
+
+  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
+      shell()->web_contents()->GetController());
+  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
+  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
+
+  EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui());
+}
+
+// Tests that all same document entries are marked as skippable together.
+IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
+                       SetSkipOnBackForwardSameDocumentEntries) {
+  // Consider the case:
+  // 1. [Z, A, (click), A#1, A#2, A#3, A#4, B]
+  // At this time all of A and A#1 through A#4 are non-skippable due to the
+  // click.
+  // 2. Let A#3 do a location.replace to another document
+  // [Z, A, A#1, A#2, Y, A#4, B]
+  // 3. Go to A#4, which is now the "current entry". All As are still
+  // non-skippable.
+  // 4. Let it now redirect without any user gesture to C.
+  // [Z, A, A#1, A#2, Y, A#4, C]
+  // At this time all of A entries should be marked as skippable.
+  // 5. Go back should skip A's and go to Z.
+
+  GURL z_url(embedded_test_server()->GetURL("/empty.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), z_url));
+
+  GURL a_url(embedded_test_server()->GetURL("/title1.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), a_url));
+
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetPrimaryFrameTree()
+                            .root();
+  EXPECT_FALSE(root->HasStickyUserActivation());
+  EXPECT_FALSE(root->HasTransientUserActivation());
+
+  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
+      shell()->web_contents()->GetController());
+
+  // Add the 2 pushstate entries. Note that ExecuteScript also sends a user
+  // gesture.
+  GURL a1_url(embedded_test_server()->GetURL("/title2.html"));
+  GURL a2_url(embedded_test_server()->GetURL("/title3.html"));
+  GURL a3_url(embedded_test_server()->GetURL(
+      "/navigation_controller/simple_page_1.html"));
+  GURL a4_url(embedded_test_server()->GetURL(
+      "/navigation_controller/simple_page_2.html"));
+  std::string script("history.pushState('', '','" + a1_url.spec() + "');");
+  ASSERT_TRUE(ExecJs(shell()->web_contents(), script));
+  script = "history.pushState('', '','" + a2_url.spec() + "');";
+  ASSERT_TRUE(ExecJs(shell()->web_contents(), script));
+  script = "history.pushState('', '','" + a3_url.spec() + "');";
+  ASSERT_TRUE(ExecJs(shell()->web_contents(), script));
+  script = "history.pushState('', '','" + a4_url.spec() + "');";
+  ASSERT_TRUE(ExecJs(shell()->web_contents(), script));
+
+  EXPECT_TRUE(root->HasStickyUserActivation());
+  EXPECT_TRUE(root->HasTransientUserActivation());
+
+  // None of the entries should be skippable.
+  EXPECT_EQ(6, controller.GetEntryCount());
+  EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(controller.GetEntryAtIndex(5)->should_skip_on_back_forward_ui());
+
+  // Navigate to B.
+  GURL b_url(embedded_test_server()->GetURL("/empty.html"));
+  EXPECT_TRUE(NavigateToURLFromRenderer(shell(), b_url));
+
+  // Go back to a3_url and do location.replace.
+  {
+    TestNavigationObserver load_observer(shell()->web_contents());
+    controller.GoToOffset(-2);
+    load_observer.Wait();
+  }
+  EXPECT_EQ(a3_url, controller.GetLastCommittedEntry()->GetURL());
+  GURL y_url(embedded_test_server()->GetURL("/frame_tree/top.html"));
+  ASSERT_TRUE(RendererLocationReplace(shell(), y_url));
+
+  EXPECT_EQ(7, controller.GetEntryCount());
+  EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(controller.GetEntryAtIndex(5)->should_skip_on_back_forward_ui());
+  EXPECT_FALSE(controller.GetEntryAtIndex(6)->should_skip_on_back_forward_ui());
+
+  // Go forward to a4_url.
+  {
+    TestNavigationObserver load_observer(shell()->web_contents());
+    controller.GoForward();
+    load_observer.Wait();
+  }
+  EXPECT_EQ(a4_url, controller.GetLastCommittedEntry()->GetURL());
+
+  // Redirect without user gesture to C.
+  GURL c_url(embedded_test_server()->GetURL("/frame_tree/top.html"));
+  EXPECT_TRUE(NavigateToURLFromRendererWithoutUserGesture(shell(), c_url));
+
+  // All entries belonging to A should be marked skippable.
+  EXPECT_EQ(7, controller.GetEntryCount());
+  EXPECT_EQ(a_url, controller.GetEntryAtIndex(1)->GetURL());
+  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
+
+  EXPECT_EQ(a1_url, controller.GetEntryAtIndex(2)->GetURL());
+  EXPECT_TRUE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui());
+
+  EXPECT_EQ(a2_url, controller.GetEntryAtIndex(3)->GetURL());
+  EXPECT_TRUE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui());
+
+  EXPECT_EQ(y_url, controller.GetEntryAtIndex(4)->GetURL());
+  EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui());
+
+  EXPECT_EQ(a4_url, controller.GetEntryAtIndex(5)->GetURL());
+  EXPECT_TRUE(controller.GetEntryAtIndex(5)->should_skip_on_back_forward_ui());
+
+  EXPECT_EQ(c_url, controller.GetEntryAtIndex(6)->GetURL());
+  EXPECT_FALSE(controller.GetEntryAtIndex(6)->should_skip_on_back_forward_ui());
+
+  // Go back should skip all A entries and go to Y.
+  {
+    TestNavigationObserver load_observer(shell()->web_contents());
+    controller.GoBack();
+    load_observer.Wait();
+  }
+  EXPECT_EQ(y_url, controller.GetLastCommittedEntry()->GetURL());
+
+  // Going back again should skip all A entries and go to Z.
+  {
+    TestNavigationObserver load_observer(shell()->web_contents());
+    controller.GoBack();
+    load_observer.Wait();
+  }
+  EXPECT_EQ(z_url, controller.GetLastCommittedEntry()->GetURL());
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    All,
+    NavigationControllerHistoryInterventionBrowserTest,
+    testing::Combine(testing::ValuesIn(RenderDocumentFeatureLevelValues()),
+                     testing::Bool()),
+    NavigationControllerHistoryInterventionBrowserTest::DescribeParams);
+INSTANTIATE_TEST_SUITE_P(
+    All,
+    NavigationControllerDebugHistoryInterventionNoUserActivation,
+    testing::Combine(testing::ValuesIn(RenderDocumentFeatureLevelValues()),
+                     testing::Bool()),
+    NavigationControllerHistoryInterventionBrowserTest::DescribeParams);
+
+}  // namespace content
diff --git a/content/browser/renderer_host/navigation_controller_impl_browsertest.cc b/content/browser/renderer_host/navigation_controller_impl_browsertest.cc
index 8d1b3bf..b5c2b4e78 100644
--- a/content/browser/renderer_host/navigation_controller_impl_browsertest.cc
+++ b/content/browser/renderer_host/navigation_controller_impl_browsertest.cc
@@ -163,19 +163,6 @@
   base::test::ScopedFeatureList feature_list_;
 };
 
-void InitBackForwardCacheFeature(base::test::ScopedFeatureList* feature_list,
-                                 bool enable_back_forward_cache) {
-  if (enable_back_forward_cache) {
-    feature_list->InitWithFeaturesAndParameters(
-        GetBasicBackForwardCacheFeatureForTesting(
-            {{kBackForwardCacheNoTimeEviction, {}},
-             {features::kBackForwardCacheMemoryControls, {}}}),
-        {});
-  } else {
-    feature_list->InitAndDisableFeature(features::kBackForwardCache);
-  }
-}
-
 class NavigationControllerBrowserTest
     : public NavigationControllerBrowserTestBase,
       public ::testing::WithParamInterface<
@@ -17383,9 +17370,6 @@
   EXPECT_EQ(url3, contents()->GetLastCommittedURL());
 }
 
-using NavigationControllerHistoryInterventionBrowserTest =
-    NavigationControllerBrowserTest;
-
 // Test to verify that after loading a post-commit error page, back is treated
 // as navigating to the entry prior to the page that was active when the
 // post-commit error page was triggered.
@@ -17518,1316 +17502,6 @@
   EXPECT_EQ(1, new_controller.GetEntryCount());
 }
 
-// Tests that the navigation entry is marked as skippable on back/forward button
-// if it does a renderer initiated navigation without ever getting a user
-// activation.
-IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
-                       NoUserActivationSetSkipOnBackForward) {
-  GURL non_skippable_url(
-      embedded_test_server()->GetURL("/frame_tree/top.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
-
-  GURL skippable_url(embedded_test_server()->GetURL("/title1.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
-
-  // It is safe to obtain the root frame tree node here, as it doesn't change.
-  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
-                            ->GetPrimaryFrameTree()
-                            .root();
-
-  EXPECT_FALSE(root->HasStickyUserActivation());
-  EXPECT_FALSE(root->HasTransientUserActivation());
-
-  // Navigate to a new same-site document from the renderer without a user
-  // gesture.
-  GURL redirected_url(embedded_test_server()->GetURL("/title2.html"));
-  EXPECT_TRUE(
-      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
-
-  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
-      shell()->web_contents()->GetController());
-  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
-
-  // Last entry should have been marked as skippable.
-  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(
-      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
-
-  EXPECT_TRUE(controller.CanGoBack());
-  // Attempt to go back or forward to the skippable entry should log the
-  // corresponding histogram and skip the corresponding entry.
-  TestNavigationObserver back_load_observer(shell()->web_contents());
-  controller.GoBack();
-  back_load_observer.Wait();
-  EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL());
-  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
-}
-
-// Same as the above test except the navigation is cross-site in this case.
-// Tests that the navigation entry is marked as skippable on back/forward button
-// if it does a renderer initiated cross-site navigation without ever getting a
-// user activation.
-IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
-                       NoUserActivationSetSkipOnBackForwardCrossSite) {
-  GURL non_skippable_url(
-      embedded_test_server()->GetURL("/frame_tree/top.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
-
-  GURL skippable_url(embedded_test_server()->GetURL("/title1.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
-
-  // It is safe to obtain the root frame tree node here, as it doesn't change.
-  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
-                            ->GetPrimaryFrameTree()
-                            .root();
-
-  EXPECT_FALSE(root->HasStickyUserActivation());
-  EXPECT_FALSE(root->HasTransientUserActivation());
-
-  // Navigate to a new cross-site document from the renderer with a user
-  // gesture.
-  GURL redirected_url(
-      embedded_test_server()->GetURL("foo.com", "/title1.html"));
-  EXPECT_TRUE(
-      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
-
-  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
-      shell()->web_contents()->GetController());
-  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
-
-  // Last entry should have been marked as skippable.
-  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(
-      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
-
-  EXPECT_TRUE(controller.CanGoBack());
-  // Attempt to go back or forward to the skippable entry should log the
-  // corresponding histogram and skip the corresponding entry.
-  TestNavigationObserver back_load_observer(shell()->web_contents());
-  controller.GoBack();
-  back_load_observer.Wait();
-  EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL());
-  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
-}
-
-// Tests that when a navigation entry is not marked as skippable the first time
-// it redirects because of user activation, that entry will be marked skippable
-// if it does another redirect without user activation after the user has come
-// back to that document again. This implies that a single user activation does
-// not mean that the user can be infintely trapped.
-IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
-                       NoUserActivationAfterReturningSetsSkippable) {
-  GURL non_skippable_url(
-      embedded_test_server()->GetURL("/frame_tree/top.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
-
-  GURL initially_non_skippable_url(
-      embedded_test_server()->GetURL("/title1.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), initially_non_skippable_url));
-
-  // It is safe to obtain the root frame tree node here, as it doesn't change.
-  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
-                            ->GetPrimaryFrameTree()
-                            .root();
-
-  EXPECT_FALSE(root->HasStickyUserActivation());
-  EXPECT_FALSE(root->HasTransientUserActivation());
-
-  // Get a user activation and navigate to a new same-site document from the
-  // renderer with a user gesture.
-  GURL redirected_url(embedded_test_server()->GetURL("/title2.html"));
-  EXPECT_TRUE(NavigateToURLFromRenderer(shell(), redirected_url));
-
-  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
-      shell()->web_contents()->GetController());
-  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
-
-  // Last entry should have not been marked as skippable.
-  EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(
-      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
-
-  // Navigate back to the earlier document's entry.
-  {
-    TestNavigationObserver back_load_observer(shell()->web_contents());
-    controller.GoBack();
-    back_load_observer.Wait();
-  }
-  EXPECT_EQ(initially_non_skippable_url,
-            controller.GetLastCommittedEntry()->GetURL());
-  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
-
-  // Navigate to a new same-site document from the renderer without a user
-  // gesture.
-  EXPECT_TRUE(
-      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
-
-  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
-
-  // Last entry should have been marked as skippable due to the lack of
-  // activation on this visit, despite not being marked skippable last time.
-  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(
-      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
-
-  // Going back now should skip the entry at [1].
-  ASSERT_TRUE(controller.CanGoBack());
-  {
-    TestNavigationObserver back_load_observer(shell()->web_contents());
-    controller.GoBack();
-    back_load_observer.Wait();
-  }
-  EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL());
-  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
-}
-
-// Tests that the navigation entry is marked as skippable on back button if it
-// does a renderer initiated navigation without ever getting a user activation.
-// Also tests this for an entry added using history.pushState.
-IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
-                       NoUserActivationSetSkippableMultipleGoBack) {
-  GURL skippable_url(embedded_test_server()->GetURL("/frame_tree/top.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
-
-  // It is safe to obtain the root frame tree node here, as it doesn't change.
-  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
-                            ->GetPrimaryFrameTree()
-                            .root();
-
-  EXPECT_FALSE(root->HasStickyUserActivation());
-  EXPECT_FALSE(root->HasTransientUserActivation());
-
-  // Navigate to a new same-site document from the renderer without a user
-  // gesture.
-  GURL redirected_url(embedded_test_server()->GetURL("/title1.html"));
-  EXPECT_TRUE(
-      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
-
-  // Use the pushState API to add another entry without user gesture.
-  GURL push_state_url(embedded_test_server()->GetURL("/title2.html"));
-  std::string script("history.pushState('', '','" + push_state_url.spec() +
-                     "');");
-  EXPECT_TRUE(
-      ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE));
-
-  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
-      shell()->web_contents()->GetController());
-  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
-
-  // Last 2 entries should have been marked as skippable.
-  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
-  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(
-      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
-
-  // CanGoBack should return false since all previous entries are skippable.
-  EXPECT_FALSE(controller.CanGoBack());
-}
-
-// Same as above but tests the metrics on going forward.
-IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
-                       NoUserActivationSetSkippableMultipleGoForward) {
-  GURL skippable_url(embedded_test_server()->GetURL("/frame_tree/top.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
-
-  // It is safe to obtain the root frame tree node here, as it doesn't change.
-  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
-                            ->GetPrimaryFrameTree()
-                            .root();
-
-  EXPECT_FALSE(root->HasStickyUserActivation());
-  EXPECT_FALSE(root->HasTransientUserActivation());
-
-  // Navigate to a new same-site document from the renderer without a user
-  // gesture.
-  GURL redirected_url(embedded_test_server()->GetURL("/title1.html"));
-  EXPECT_TRUE(
-      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
-
-  // Use the pushState API to add another entry without user gesture.
-  GURL push_state_url(embedded_test_server()->GetURL("/title2.html"));
-  std::string script("history.pushState('', '','" + push_state_url.spec() +
-                     "');");
-  EXPECT_TRUE(
-      ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE));
-
-  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
-      shell()->web_contents()->GetController());
-  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
-
-  // Last 2 entries should have been marked as skippable.
-  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
-  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(
-      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
-}
-
-// Tests that if an entry is marked as skippable, it will not be reset if there
-// is a navigation to this entry again (crbug.com/112129).
-IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
-                       DoNotResetSkipOnBackForward) {
-  GURL main_url(embedded_test_server()->GetURL("/frame_tree/top.html"));
-
-  EXPECT_TRUE(NavigateToURL(shell(), main_url));
-
-  // It is safe to obtain the root frame tree node here, as it doesn't change.
-  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
-                            ->GetPrimaryFrameTree()
-                            .root();
-
-  EXPECT_FALSE(root->HasStickyUserActivation());
-  EXPECT_FALSE(root->HasTransientUserActivation());
-
-  // Navigate to a new same-site document from the renderer without a user
-  // gesture.
-  GURL url(embedded_test_server()->GetURL("/title1.html"));
-  EXPECT_TRUE(NavigateToURLFromRendererWithoutUserGesture(shell(), url));
-
-  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
-      shell()->web_contents()->GetController());
-  EXPECT_EQ(1, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
-
-  // Last entry should have been marked as skippable.
-  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(
-      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
-
-  // Go back to the last entry.
-  TestNavigationObserver back_nav_load_observer(shell()->web_contents());
-  controller.GoToIndex(0);
-  back_nav_load_observer.Wait();
-
-  // Going back again to an entry should not reset its skippable flag.
-  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
-
-  // Navigating away from this with a browser initiated navigation should log a
-  // histogram with skippable as true.
-  GURL url1(embedded_test_server()->GetURL("/title2.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), url1));
-}
-
-// Tests that if an entry is marked as skippable, it will not be reset if there
-// is a navigation to this entry again (crbug.com/1121293) using history.back/
-// forward.
-IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
-                       DoNotResetSkipOnHistoryBackAPI) {
-  GURL main_url(embedded_test_server()->GetURL("/frame_tree/top.html"));
-
-  EXPECT_TRUE(NavigateToURL(shell(), main_url));
-
-  // It is safe to obtain the root frame tree node here, as it doesn't change.
-  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
-                            ->GetPrimaryFrameTree()
-                            .root();
-
-  EXPECT_FALSE(root->HasStickyUserActivation());
-  EXPECT_FALSE(root->HasTransientUserActivation());
-
-  // Navigate to a new same-site document from the renderer without a user
-  // gesture.
-  GURL url(embedded_test_server()->GetURL("/title1.html"));
-  EXPECT_TRUE(NavigateToURLFromRendererWithoutUserGesture(shell(), url));
-
-  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
-      shell()->web_contents()->GetController());
-  EXPECT_EQ(1, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
-
-  // Last entry should have been marked as skippable.
-  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(
-      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
-
-  // Go back to the last entry using history.back.
-  EXPECT_TRUE(
-      ExecJs(shell(), "history.back();", EXECUTE_SCRIPT_NO_USER_GESTURE));
-  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
-
-  // Going back again to an entry should not reset its skippable flag.
-  EXPECT_TRUE(
-      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
-  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
-}
-
-// Tests that if a navigation entry is marked as skippable due to pushState then
-// the flag should be reset if there is a user gesture on this document. All of
-// the adjacent entries belonging to the same document will have their skippable
-// bits reset.
-IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
-                       OnUserGestureResetSameDocumentEntriesSkipFlag) {
-  GURL skippable_url(embedded_test_server()->GetURL("/frame_tree/top.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
-
-  // It is safe to obtain the root frame tree node here, as it doesn't change.
-  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
-                            ->GetPrimaryFrameTree()
-                            .root();
-
-  EXPECT_FALSE(root->HasStickyUserActivation());
-  EXPECT_FALSE(root->HasTransientUserActivation());
-
-  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
-      shell()->web_contents()->GetController());
-
-  // Redirect to another page without a user gesture.
-  GURL redirected_url(embedded_test_server()->GetURL("/empty.html"));
-  EXPECT_TRUE(
-      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
-  // Last entry should have been marked as skippable.
-  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
-
-  // Use the pushState API to add another entry without user gesture.
-  GURL push_state_url1(embedded_test_server()->GetURL("/title1.html"));
-  std::string script("history.pushState('', '','" + push_state_url1.spec() +
-                     "');");
-  EXPECT_TRUE(
-      ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE));
-
-  // Use the pushState API to add another entry without user gesture.
-  GURL push_state_url2(embedded_test_server()->GetURL("/title2.html"));
-  script = "history.pushState('', '','" + push_state_url2.spec() + "');";
-  EXPECT_TRUE(
-      ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE));
-
-  EXPECT_EQ(3, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(3, controller.GetLastCommittedEntryIndex());
-
-  // We now have
-  // [skippable_url(skip), redirected_url(skip), push_state_url1(skip),
-  // push_state_url2*]
-  // Last 2 entries should have been marked as skippable.
-  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
-  EXPECT_TRUE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(
-      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
-
-  EXPECT_EQ(skippable_url, controller.GetEntryAtIndex(0)->GetURL());
-  EXPECT_EQ(redirected_url, controller.GetEntryAtIndex(1)->GetURL());
-  EXPECT_EQ(push_state_url1, controller.GetEntryAtIndex(2)->GetURL());
-  EXPECT_EQ(push_state_url2, controller.GetEntryAtIndex(3)->GetURL());
-
-  // Do another pushState so push_state_url2's entry also becomes skippable.
-  GURL push_state_url3(embedded_test_server()->GetURL("/title3.html"));
-  script = "history.pushState('', '','" + push_state_url3.spec() + "');";
-  EXPECT_TRUE(
-      ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE));
-  EXPECT_TRUE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui());
-  // We now have
-  // [skippable_url(skip), redirected_url(skip), push_state_url1(skip),
-  // push_state_url2(skip), push_state_url3*]
-
-  // Go to index 2.
-  TestNavigationObserver load_observer(shell()->web_contents());
-  controller.GoToIndex(2);
-  load_observer.Wait();
-  EXPECT_EQ(push_state_url1, controller.GetLastCommittedEntry()->GetURL());
-
-  // We now have (Before user gesture)
-  // [skippable_url(skip), redirected_url(skip), push_state_url1(skip)*,
-  // push_state_url2(skip), push_state_url3]
-  // Note the entry at index 2 retains its skippable flag.
-  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
-  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
-  EXPECT_TRUE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui());
-  EXPECT_TRUE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui());
-
-  // Simulate a user gesture. ExecuteScript internally also sends a user
-  // gesture.
-  script = "a=5";
-  EXPECT_TRUE(content::ExecJs(shell()->web_contents(), script));
-
-  // We now have (After user gesture)
-  // [skippable_url(skip), redirected_url, push_state_url1*, push_state_url2,
-  // push_state_url3]
-  // All the navigations that refer to the same document should have their
-  // skippable bit reset.
-  EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui());
-  // The first entry is not the same document and its bit should not be reset.
-  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
-
-  // goBack should now navigate to entry at index 1.
-  TestNavigationObserver back_load_observer(shell()->web_contents());
-  controller.GoBack();
-  back_load_observer.Wait();
-  EXPECT_EQ(redirected_url, controller.GetLastCommittedEntry()->GetURL());
-
-  // Do another pushState without user gesture.
-  GURL push_state_url4(embedded_test_server()->GetURL("/title3.html"));
-  script = "history.pushState('', '','" + push_state_url3.spec() + "');";
-  EXPECT_TRUE(
-      ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE));
-  // We now have
-  // [skippable_url(skip), redirected_url, push_state_url4*]
-  EXPECT_EQ(3, controller.GetEntryCount());
-  EXPECT_EQ(skippable_url, controller.GetEntryAtIndex(0)->GetURL());
-  EXPECT_EQ(redirected_url, controller.GetEntryAtIndex(1)->GetURL());
-  EXPECT_EQ(push_state_url4, controller.GetEntryAtIndex(2)->GetURL());
-  // The skippable flag will still be unset since this page has seen a user
-  // gesture once.
-  EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
-}
-
-class NavigationControllerDebugHistoryInterventionNoUserActivation
-    : public NavigationControllerBrowserTest {
- protected:
-  void SetUp() override {
-    feature_list_.InitAndEnableFeature(
-        features::kDebugHistoryInterventionNoUserActivation);
-    NavigationControllerBrowserTest::SetUp();
-  }
-
- private:
-  base::test::ScopedFeatureList feature_list_;
-};
-
-// Tests that if a navigation entry is marked as skippable due to pushState then
-// the flag is not reset even if there is a user gesture on this document, when
-// the debug flag is enabled. This is to check the case where there wasn't
-// actually a user gesture but one is being reported somehow.
-// (See crbug.com/1201355)
-IN_PROC_BROWSER_TEST_P(
-    NavigationControllerDebugHistoryInterventionNoUserActivation,
-    OnUserGestureDoNotResetSameDocumentEntriesSkipFlag) {
-  GURL skippable_url(embedded_test_server()->GetURL("/frame_tree/top.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
-
-  // It is safe to obtain the root frame tree node here, as it doesn't change.
-  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
-                            ->GetPrimaryFrameTree()
-                            .root();
-
-  EXPECT_FALSE(root->HasStickyUserActivation());
-  EXPECT_FALSE(root->HasTransientUserActivation());
-
-  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
-      shell()->web_contents()->GetController());
-
-  // Redirect to another page without a user gesture.
-  GURL redirected_url(embedded_test_server()->GetURL("/empty.html"));
-  EXPECT_TRUE(
-      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
-  // Last entry should have been marked as skippable.
-  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
-
-  // Use the pushState API to add another entry without user gesture.
-  GURL push_state_url1(embedded_test_server()->GetURL("/title1.html"));
-  std::string script("history.pushState('', '','" + push_state_url1.spec() +
-                     "');");
-  EXPECT_TRUE(
-      ExecJs(shell()->web_contents(), script, EXECUTE_SCRIPT_NO_USER_GESTURE));
-
-  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
-
-  // We now have
-  // [skippable_url(skip), redirected_url(skip), push_state_url1*]
-  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(
-      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
-
-  EXPECT_EQ(skippable_url, controller.GetEntryAtIndex(0)->GetURL());
-  EXPECT_EQ(redirected_url, controller.GetEntryAtIndex(1)->GetURL());
-  EXPECT_EQ(push_state_url1, controller.GetEntryAtIndex(2)->GetURL());
-
-  // Simulate a user gesture. ExecuteScript internally also sends a user
-  // gesture. The skippable bit for [1] should not have changed because of the
-  // DebugHistoryInterventionNoUserActivation flag.
-  script = "a=5";
-  EXPECT_TRUE(content::ExecJs(shell()->web_contents(), script));
-
-  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
-  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
-}
-
-// Tests that if a navigation entry is marked as skippable due to redirect to a
-// new document then the flag should not be reset if there is a user gesture on
-// the new document.
-IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
-                       OnUserGestureDoNotResetDifferentDocumentEntrySkipFlag) {
-  GURL skippable_url(embedded_test_server()->GetURL("/frame_tree/top.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
-
-  // It is safe to obtain the root frame tree node here, as it doesn't change.
-  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
-                            ->GetPrimaryFrameTree()
-                            .root();
-
-  EXPECT_FALSE(root->HasStickyUserActivation());
-  EXPECT_FALSE(root->HasTransientUserActivation());
-
-  // Navigate to a new same-site document from the renderer without a user
-  // gesture.
-  GURL redirected_url(embedded_test_server()->GetURL("/title1.html"));
-  EXPECT_TRUE(
-      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
-
-  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
-      shell()->web_contents()->GetController());
-  EXPECT_EQ(1, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
-
-  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(
-      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
-
-  // Simulate a user gesture.
-  root->UpdateUserActivationState(
-      blink::mojom::UserActivationUpdateType::kNotifyActivation,
-      blink::mojom::UserActivationNotificationType::kTest);
-
-  // Since the last navigations refer to a different document, a user gesture
-  // here should not reset the skippable bit in the previous entries.
-  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
-}
-
-// Tests that the navigation entry is not marked as skippable on back/forward
-// button if it does a renderer initiated navigation after getting a user
-// activation.
-IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
-                       UserActivationDoNotSkipOnBackForward) {
-  GURL non_skippable_url(
-      embedded_test_server()->GetURL("/frame_tree/top.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
-
-  // It is safe to obtain the root frame tree node here, as it doesn't change.
-  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
-                            ->GetPrimaryFrameTree()
-                            .root();
-
-  EXPECT_FALSE(root->HasStickyUserActivation());
-  EXPECT_FALSE(root->HasTransientUserActivation());
-
-  // Navigate to a new same-site document from the renderer.
-  // Note that NavigateToURLFromRenderer also simulates a user gesture.
-  GURL user_gesture_redirected_url(
-      embedded_test_server()->GetURL("/title1.html"));
-  EXPECT_TRUE(NavigateToURLFromRenderer(shell(), user_gesture_redirected_url));
-
-  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
-      shell()->web_contents()->GetController());
-  EXPECT_EQ(1, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
-
-  // Last entry should not have been marked as skippable.
-  EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(
-      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
-
-  // Nothing should get skipped when back button is clicked.
-  TestNavigationObserver back_nav_load_observer(shell()->web_contents());
-  controller.GoBack();
-  back_nav_load_observer.Wait();
-  EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL());
-  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
-}
-
-// Tests that the navigation entry should not be marked as skippable on
-// back/forward button if it is navigated away using a browser initiated
-// navigation.
-IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
-                       BrowserInitiatedNavigationDoNotSkipOnBackForward) {
-  GURL non_skippable_url(
-      embedded_test_server()->GetURL("/frame_tree/top.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
-
-  // It is safe to obtain the root frame tree node here, as it doesn't change.
-  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
-                            ->GetPrimaryFrameTree()
-                            .root();
-
-  EXPECT_FALSE(root->HasStickyUserActivation());
-  EXPECT_FALSE(root->HasTransientUserActivation());
-
-  GURL url(embedded_test_server()->GetURL("/title1.html"));
-
-  // Note that NavigateToURL simulates a browser initiated navigation.
-  EXPECT_TRUE(NavigateToURL(shell(), url));
-
-  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
-      shell()->web_contents()->GetController());
-  EXPECT_EQ(1, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
-
-  // Last entry should not have been marked as skippable.
-  EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(
-      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
-
-  // Nothing should get skipped when back button is clicked.
-  TestNavigationObserver back_nav_load_observer(shell()->web_contents());
-  controller.GoBack();
-  back_nav_load_observer.Wait();
-  EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL());
-  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
-}
-
-// Tests that the navigation entry that is marked as skippable on back/forward
-// button does not get skipped for history.back API calls.
-IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
-                       SetSkipOnBackDoNotSkipForHistoryBackAPI) {
-  GURL non_skippable_url(
-      embedded_test_server()->GetURL("/frame_tree/top.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
-
-  GURL skippable_url(embedded_test_server()->GetURL("/title1.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
-
-  // It is safe to obtain the root frame tree node here, as it doesn't change.
-  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
-                            ->GetPrimaryFrameTree()
-                            .root();
-
-  EXPECT_FALSE(root->HasStickyUserActivation());
-  EXPECT_FALSE(root->HasTransientUserActivation());
-
-  // Navigate to a new same-site document from the renderer without a user
-  // gesture.
-  GURL redirected_url(embedded_test_server()->GetURL("/title2.html"));
-  EXPECT_TRUE(
-      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
-
-  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
-      shell()->web_contents()->GetController());
-  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
-
-  // Last entry should have been marked as skippable.
-  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(
-      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
-
-  // Attempt to go back to the skippable entry using the History API should
-  // not skip the corresponding entry.
-  TestNavigationObserver frame_observer(shell()->web_contents());
-  EXPECT_TRUE(ExecJs(root, "window.history.back()"));
-  frame_observer.Wait();
-
-  EXPECT_EQ(skippable_url, controller.GetLastCommittedEntry()->GetURL());
-  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
-}
-
-#if BUILDFLAG(IS_ANDROID)
-// Test GoToOffset with enable history intervention.
-IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
-                       GoToOffsetWithSkippingEnableHistoryIntervention) {
-  base::HistogramTester histograms;
-  GURL non_skippable_url(
-      embedded_test_server()->GetURL("/frame_tree/top.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
-
-  GURL skippable_url(embedded_test_server()->GetURL("/title1.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
-
-  // It is safe to obtain the root frame tree node here, as it doesn't change.
-  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
-                            ->GetPrimaryFrameTree()
-                            .root();
-
-  EXPECT_FALSE(root->HasStickyUserActivation());
-  EXPECT_FALSE(root->HasTransientUserActivation());
-
-  // Navigate to a new same-site document from the renderer without a user
-  // gesture.
-  GURL redirected_url(embedded_test_server()->GetURL("/title2.html"));
-  EXPECT_TRUE(
-      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
-
-  GURL skippable_url2(embedded_test_server()->GetURL("/title3.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), skippable_url2));
-
-  EXPECT_FALSE(root->HasStickyUserActivation());
-  EXPECT_FALSE(root->HasTransientUserActivation());
-
-  // Navigate to a new same-site document from the renderer without a user
-  // gesture.
-  GURL redirected_url2(embedded_test_server()->GetURL("/title4.html"));
-  EXPECT_TRUE(
-      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url2));
-
-  // CanGoToOffset should visit the skippable entries while
-  // CanGoToOffsetWithSKipping will skip the skippable entries.
-  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
-      shell()->web_contents()->GetController());
-  EXPECT_TRUE(controller.CanGoToOffset(-3));
-  EXPECT_TRUE(controller.CanGoToOffset(-4));
-  EXPECT_FALSE(controller.CanGoToOffsetWithSkipping(-3));
-
-  TestNavigationObserver nav_observer(shell()->web_contents());
-  controller.GoToOffset(-4);
-  nav_observer.Wait();
-  EXPECT_EQ(0, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
-  EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL());
-}
-#endif  // BUILDFLAG(IS_ANDROID)
-
-// Tests that the navigation entry that is marked as skippable on back/forward
-// button does not get skipped for GoToOffset calls.
-// This covers actions in the following scenario:
-// [non_skippable_url, skippable_url, redirected_url, skippable_url2,
-// redirected_url2]
-IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
-                       SetSkipOnBackForwardDoNotSkipForGoToOffset) {
-  GURL non_skippable_url(
-      embedded_test_server()->GetURL("/frame_tree/top.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
-
-  GURL skippable_url(embedded_test_server()->GetURL("/title1.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
-
-  // It is safe to obtain the root frame tree node here, as it doesn't change.
-  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
-                            ->GetPrimaryFrameTree()
-                            .root();
-
-  EXPECT_FALSE(root->HasStickyUserActivation());
-  EXPECT_FALSE(root->HasTransientUserActivation());
-
-  // Navigate to a new same-site document from the renderer without a user
-  // gesture.
-  GURL redirected_url(embedded_test_server()->GetURL("/title2.html"));
-  EXPECT_TRUE(
-      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
-
-  GURL skippable_url2(embedded_test_server()->GetURL("/title3.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), skippable_url2));
-
-  EXPECT_FALSE(root->HasStickyUserActivation());
-  EXPECT_FALSE(root->HasTransientUserActivation());
-
-  // Navigate to a new same-site document from the renderer without a user
-  // gesture.
-  GURL redirected_url2(embedded_test_server()->GetURL("/title4.html"));
-  EXPECT_TRUE(
-      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url2));
-
-  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
-      shell()->web_contents()->GetController());
-  EXPECT_EQ(4, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(4, controller.GetLastCommittedEntryIndex());
-
-  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui());
-  EXPECT_TRUE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui());
-
-  EXPECT_TRUE(controller.CanGoToOffset(-3));
-
-  // GoToOffset should visit the skippable entries.
-  TestNavigationObserver nav_observer1(shell()->web_contents());
-  controller.GoToOffset(-1);
-  nav_observer1.Wait();
-  EXPECT_EQ(3, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(3, controller.GetLastCommittedEntryIndex());
-  EXPECT_EQ(skippable_url2, controller.GetLastCommittedEntry()->GetURL());
-
-  TestNavigationObserver nav_observer2(shell()->web_contents());
-  controller.GoToOffset(1);
-  nav_observer2.Wait();
-  EXPECT_EQ(4, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(4, controller.GetLastCommittedEntryIndex());
-  EXPECT_EQ(redirected_url2, controller.GetLastCommittedEntry()->GetURL());
-
-  TestNavigationObserver nav_observer3(shell()->web_contents());
-  controller.GoToOffset(-4);
-  nav_observer3.Wait();
-  EXPECT_EQ(0, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
-  EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL());
-
-  EXPECT_TRUE(controller.CanGoToOffset(4));
-
-  TestNavigationObserver nav_observer4(shell()->web_contents());
-  controller.GoToOffset(4);
-  nav_observer4.Wait();
-  EXPECT_EQ(4, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(4, controller.GetLastCommittedEntryIndex());
-  EXPECT_EQ(redirected_url2, controller.GetLastCommittedEntry()->GetURL());
-}
-
-// Tests that the navigation entry that is marked as skippable on back/forward
-// button is skipped for GoToOffset calls.
-// This covers actions in the following scenario:
-// [non_skippable_url, skippable_url, redirected_url, skippable_url2,
-// redirected_url2]
-IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
-                       SetSkipOnBackForwardDoSkipForGoToOffsetWithSkipping) {
-#if BUILDFLAG(IS_ANDROID)
-  GURL non_skippable_url(
-      embedded_test_server()->GetURL("/frame_tree/top.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
-
-  GURL skippable_url(embedded_test_server()->GetURL("/title1.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
-
-  // It is safe to obtain the root frame tree node here, as it doesn't change.
-  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
-                            ->GetPrimaryFrameTree()
-                            .root();
-
-  EXPECT_FALSE(root->HasStickyUserActivation());
-  EXPECT_FALSE(root->HasTransientUserActivation());
-
-  // Navigate to a new same-site document from the renderer without a user
-  // gesture.
-  GURL redirected_url(embedded_test_server()->GetURL("/title2.html"));
-  EXPECT_TRUE(
-      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
-
-  GURL skippable_url2(embedded_test_server()->GetURL("/title3.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), skippable_url2));
-
-  EXPECT_FALSE(root->HasStickyUserActivation());
-  EXPECT_FALSE(root->HasTransientUserActivation());
-
-  // Navigate to a new same-site document from the renderer without a user
-  // gesture.
-  GURL redirected_url2(embedded_test_server()->GetURL("/title4.html"));
-  EXPECT_TRUE(
-      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url2));
-
-  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
-      shell()->web_contents()->GetController());
-  EXPECT_EQ(4, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(4, controller.GetLastCommittedEntryIndex());
-
-  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui());
-  EXPECT_TRUE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui());
-
-  EXPECT_FALSE(controller.CanGoToOffsetWithSkipping(-3));
-  EXPECT_TRUE(controller.CanGoToOffsetWithSkipping(-2));
-
-  // GoToOffset should skip the skippable entries.
-  TestNavigationObserver nav_observer1(shell()->web_contents());
-  controller.GoToOffsetWithSkipping(-1);
-  nav_observer1.Wait();
-  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
-  EXPECT_EQ(redirected_url, controller.GetLastCommittedEntry()->GetURL());
-
-  TestNavigationObserver nav_observer2(shell()->web_contents());
-  controller.GoToOffsetWithSkipping(1);
-  nav_observer2.Wait();
-  EXPECT_EQ(4, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(4, controller.GetLastCommittedEntryIndex());
-  EXPECT_EQ(redirected_url2, controller.GetLastCommittedEntry()->GetURL());
-
-  TestNavigationObserver nav_observer3(shell()->web_contents());
-  controller.GoToOffsetWithSkipping(-2);
-  nav_observer3.Wait();
-  EXPECT_EQ(0, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
-  EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL());
-
-  EXPECT_FALSE(controller.CanGoToOffsetWithSkipping(3));
-  EXPECT_TRUE(controller.CanGoToOffsetWithSkipping(2));
-
-  TestNavigationObserver nav_observer4(shell()->web_contents());
-  controller.GoToOffsetWithSkipping(2);
-  nav_observer4.Wait();
-  EXPECT_EQ(4, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(4, controller.GetLastCommittedEntryIndex());
-  EXPECT_EQ(redirected_url2, controller.GetLastCommittedEntry()->GetURL());
-#endif  // BUILDFLAG(IS_ANDROID)
-}
-
-// Tests that the navigation entry that is marked as skippable on back/forward
-// button does not get skipped for history.forward API calls.
-IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
-                       SetSkipOnBackDoNotSkipForHistoryForwardAPI) {
-  GURL non_skippable_url(
-      embedded_test_server()->GetURL("/frame_tree/top.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
-
-  GURL skippable_url(embedded_test_server()->GetURL("/title1.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
-
-  // It is safe to obtain the root frame tree node here, as it doesn't change.
-  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
-                            ->GetPrimaryFrameTree()
-                            .root();
-
-  EXPECT_FALSE(root->HasStickyUserActivation());
-  EXPECT_FALSE(root->HasTransientUserActivation());
-
-  // Navigate to a new same-site document from the renderer without a user
-  // gesture.
-  GURL redirected_url(embedded_test_server()->GetURL("/title2.html"));
-  EXPECT_TRUE(
-      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
-
-  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
-      shell()->web_contents()->GetController());
-  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
-
-  // Last entry should have been marked as skippable.
-  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(
-      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
-
-  TestNavigationObserver nav_observer1(shell()->web_contents());
-  controller.GoToIndex(0);
-  nav_observer1.Wait();
-  EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL());
-
-  // Attempt to go forward to the skippable entry using the History API should
-  // not skip the corresponding entry.
-  TestNavigationObserver nav_observer2(shell()->web_contents());
-  EXPECT_TRUE(ExecJs(root, "window.history.forward()"));
-  nav_observer2.Wait();
-
-  EXPECT_EQ(skippable_url, controller.GetLastCommittedEntry()->GetURL());
-  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
-}
-
-// Tests that the oldest navigation entry that is marked as skippable is the one
-// that is pruned if max entry count is reached.
-IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
-                       PruneOldestSkippableEntry) {
-  // Set the max entry count as 3.
-  NavigationControllerImpl::set_max_entry_count_for_testing(3);
-
-  GURL non_skippable_url(
-      embedded_test_server()->GetURL("/frame_tree/top.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
-
-  GURL skippable_url(embedded_test_server()->GetURL("/title1.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
-
-  // It is safe to obtain the root frame tree node here, as it doesn't change.
-  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
-                            ->GetPrimaryFrameTree()
-                            .root();
-
-  EXPECT_FALSE(root->HasStickyUserActivation());
-  EXPECT_FALSE(root->HasTransientUserActivation());
-
-  // Navigate to a new same-site document from the renderer without a user
-  // gesture.
-  GURL redirected_url(embedded_test_server()->GetURL("/title2.html"));
-  EXPECT_TRUE(
-      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
-
-  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
-      shell()->web_contents()->GetController());
-  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
-  EXPECT_EQ(3, controller.GetEntryCount());
-  EXPECT_EQ(non_skippable_url, controller.GetEntryAtIndex(0)->GetURL());
-  EXPECT_EQ(skippable_url, controller.GetEntryAtIndex(1)->GetURL());
-  EXPECT_EQ(redirected_url, controller.GetEntryAtIndex(2)->GetURL());
-
-  // |skippable_url| entry should have been marked as skippable.
-  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(
-      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
-
-  // A new navigation should lead to |skippable_url| to be pruned.
-  GURL new_navigation_url(embedded_test_server()->GetURL("/title3.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), new_navigation_url));
-  // Should still have 3 entries.
-  EXPECT_EQ(3, controller.GetEntryCount());
-  EXPECT_EQ(non_skippable_url, controller.GetEntryAtIndex(0)->GetURL());
-  EXPECT_EQ(redirected_url, controller.GetEntryAtIndex(1)->GetURL());
-  EXPECT_EQ(new_navigation_url, controller.GetEntryAtIndex(2)->GetURL());
-}
-
-// Tests that we fallback to pruning the oldest entry if the last committed
-// entry is the oldest skippable navigation entry.
-IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
-                       PruneOldestWhenLastCommittedIsSkippable) {
-  // Set the max entry count as 2.
-  NavigationControllerImpl::set_max_entry_count_for_testing(2);
-
-  GURL non_skippable_url(
-      embedded_test_server()->GetURL("/frame_tree/top.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
-
-  GURL skippable_url(embedded_test_server()->GetURL("/title1.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
-
-  // It is safe to obtain the root frame tree node here, as it doesn't change.
-  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
-                            ->GetPrimaryFrameTree()
-                            .root();
-
-  EXPECT_FALSE(root->HasStickyUserActivation());
-  EXPECT_FALSE(root->HasTransientUserActivation());
-
-  // Navigate to a new same-site document from the renderer without a user
-  // gesture. This will mark |skippable_url| as skippable but since that is also
-  // the last committed entry, it will not be pruned. Instead the oldest entry
-  // will be removed.
-  GURL redirected_url(embedded_test_server()->GetURL("/title2.html"));
-  EXPECT_TRUE(
-      NavigateToURLFromRendererWithoutUserGesture(shell(), redirected_url));
-
-  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
-      shell()->web_contents()->GetController());
-  EXPECT_EQ(1, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
-  EXPECT_EQ(2, controller.GetEntryCount());
-  EXPECT_EQ(skippable_url, controller.GetEntryAtIndex(0)->GetURL());
-  EXPECT_EQ(redirected_url, controller.GetEntryAtIndex(1)->GetURL());
-
-  // |skippable_url| entry should have been marked as skippable.
-  EXPECT_TRUE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(
-      controller.GetLastCommittedEntry()->should_skip_on_back_forward_ui());
-}
-
-// Tests that the navigation entry is marked as skippable on back/forward
-// button if a subframe does a push state without ever getting a user
-// activation.
-IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
-                       NoUserActivationSetSkipOnBackForwardSubframe) {
-  GURL non_skippable_url(embedded_test_server()->GetURL("/title1.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
-
-  // It is safe to obtain the root frame tree node here, as it doesn't change.
-  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
-                            ->GetPrimaryFrameTree()
-                            .root();
-
-  GURL skippable_url(
-      embedded_test_server()->GetURL("/frame_tree/page_with_one_frame.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), skippable_url));
-
-  EXPECT_FALSE(root->HasStickyUserActivation());
-  EXPECT_FALSE(root->HasTransientUserActivation());
-
-  // Invoke pushstate from a subframe.
-  std::string script = "history.pushState({}, 'page 1', 'simple_page_1.html')";
-  EXPECT_TRUE(
-      ExecJs(root->child_at(0), script, EXECUTE_SCRIPT_NO_USER_GESTURE));
-
-  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
-      shell()->web_contents()->GetController());
-  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
-
-  EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
-  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui());
-
-  EXPECT_TRUE(controller.CanGoBack());
-
-  // Attempt to go back or forward to the skippable entry should log the
-  // corresponding histogram and skip the corresponding entry.
-  TestNavigationObserver back_load_observer(shell()->web_contents());
-  controller.GoBack();
-  back_load_observer.Wait();
-  EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL());
-  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
-
-  // Go forward to the 3rd entry.
-  TestNavigationObserver load_observer(shell()->web_contents());
-  controller.GoToIndex(2);
-  load_observer.Wait();
-
-  // A user gesture in the main frame now will lead to all same document
-  // entries to be marked as non-skippable.
-  root->UpdateUserActivationState(
-      blink::mojom::UserActivationUpdateType::kNotifyActivation,
-      blink::mojom::UserActivationNotificationType::kTest);
-  EXPECT_TRUE(root->HasStickyUserActivation());
-  EXPECT_TRUE(root->HasTransientUserActivation());
-  EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui());
-}
-
-// Tests that the navigation entry is not marked as skippable on back/forward
-// button if a subframe does a push state without ever getting a user
-// activation on itself but there was a user gesture on the main frame.
-IN_PROC_BROWSER_TEST_P(
-    NavigationControllerHistoryInterventionBrowserTest,
-    UserActivationMainFrameDoNotSetSkipOnBackForwardSubframe) {
-  GURL non_skippable_url(embedded_test_server()->GetURL("/title1.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url));
-
-  // It is safe to obtain the root frame tree node here, as it doesn't change.
-  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
-                            ->GetPrimaryFrameTree()
-                            .root();
-
-  GURL url_with_frames(
-      embedded_test_server()->GetURL("/frame_tree/page_with_one_frame.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), url_with_frames));
-
-  EXPECT_FALSE(root->HasStickyUserActivation());
-  EXPECT_FALSE(root->HasTransientUserActivation());
-
-  // Simulate user gesture in the main frame. Subframes creating entries without
-  // user gesture will not lead to the last committed entry being marked as
-  // skippable.
-  root->UpdateUserActivationState(
-      blink::mojom::UserActivationUpdateType::kNotifyActivation,
-      blink::mojom::UserActivationNotificationType::kTest);
-  EXPECT_TRUE(root->HasStickyUserActivation());
-  EXPECT_TRUE(root->HasTransientUserActivation());
-
-  // Invoke pushstate from a subframe.
-  std::string script = "history.pushState({}, 'page 1', 'simple_page_1.html')";
-  EXPECT_TRUE(
-      ExecJs(root->child_at(0), script, EXECUTE_SCRIPT_NO_USER_GESTURE));
-
-  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
-      shell()->web_contents()->GetController());
-  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
-  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
-
-  EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui());
-}
-
-// Tests that all same document entries are marked as skippable together.
-IN_PROC_BROWSER_TEST_P(NavigationControllerHistoryInterventionBrowserTest,
-                       SetSkipOnBackForwardSameDocumentEntries) {
-  // Consider the case:
-  // 1. [Z, A, (click), A#1, A#2, A#3, A#4, B]
-  // At this time all of A and A#1 through A#4 are non-skippable due to the
-  // click.
-  // 2. Let A#3 do a location.replace to another document
-  // [Z, A, A#1, A#2, Y, A#4, B]
-  // 3. Go to A#4, which is now the "current entry". All As are still
-  // non-skippable.
-  // 4. Let it now redirect without any user gesture to C.
-  // [Z, A, A#1, A#2, Y, A#4, C]
-  // At this time all of A entries should be marked as skippable.
-  // 5. Go back should skip A's and go to Z.
-
-  GURL z_url(embedded_test_server()->GetURL("/empty.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), z_url));
-
-  GURL a_url(embedded_test_server()->GetURL("/title1.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), a_url));
-
-  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
-                            ->GetPrimaryFrameTree()
-                            .root();
-  EXPECT_FALSE(root->HasStickyUserActivation());
-  EXPECT_FALSE(root->HasTransientUserActivation());
-
-  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
-      shell()->web_contents()->GetController());
-
-  // Add the 2 pushstate entries. Note that ExecuteScript also sends a user
-  // gesture.
-  GURL a1_url(embedded_test_server()->GetURL("/title2.html"));
-  GURL a2_url(embedded_test_server()->GetURL("/title3.html"));
-  GURL a3_url(embedded_test_server()->GetURL(
-      "/navigation_controller/simple_page_1.html"));
-  GURL a4_url(embedded_test_server()->GetURL(
-      "/navigation_controller/simple_page_2.html"));
-  std::string script("history.pushState('', '','" + a1_url.spec() + "');");
-  ASSERT_TRUE(ExecJs(shell()->web_contents(), script));
-  script = "history.pushState('', '','" + a2_url.spec() + "');";
-  ASSERT_TRUE(ExecJs(shell()->web_contents(), script));
-  script = "history.pushState('', '','" + a3_url.spec() + "');";
-  ASSERT_TRUE(ExecJs(shell()->web_contents(), script));
-  script = "history.pushState('', '','" + a4_url.spec() + "');";
-  ASSERT_TRUE(ExecJs(shell()->web_contents(), script));
-
-  EXPECT_TRUE(root->HasStickyUserActivation());
-  EXPECT_TRUE(root->HasTransientUserActivation());
-
-  // None of the entries should be skippable.
-  EXPECT_EQ(6, controller.GetEntryCount());
-  EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(controller.GetEntryAtIndex(5)->should_skip_on_back_forward_ui());
-
-  // Navigate to B.
-  GURL b_url(embedded_test_server()->GetURL("/empty.html"));
-  EXPECT_TRUE(NavigateToURLFromRenderer(shell(), b_url));
-
-  // Go back to a3_url and do location.replace.
-  {
-    TestNavigationObserver load_observer(shell()->web_contents());
-    controller.GoToOffset(-2);
-    load_observer.Wait();
-  }
-  EXPECT_EQ(a3_url, controller.GetLastCommittedEntry()->GetURL());
-  GURL y_url(embedded_test_server()->GetURL("/frame_tree/top.html"));
-  ASSERT_TRUE(RendererLocationReplace(shell(), y_url));
-
-  EXPECT_EQ(7, controller.GetEntryCount());
-  EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(controller.GetEntryAtIndex(5)->should_skip_on_back_forward_ui());
-  EXPECT_FALSE(controller.GetEntryAtIndex(6)->should_skip_on_back_forward_ui());
-
-  // Go forward to a4_url.
-  {
-    TestNavigationObserver load_observer(shell()->web_contents());
-    controller.GoForward();
-    load_observer.Wait();
-  }
-  EXPECT_EQ(a4_url, controller.GetLastCommittedEntry()->GetURL());
-
-  // Redirect without user gesture to C.
-  GURL c_url(embedded_test_server()->GetURL("/frame_tree/top.html"));
-  EXPECT_TRUE(NavigateToURLFromRendererWithoutUserGesture(shell(), c_url));
-
-  // All entries belonging to A should be marked skippable.
-  EXPECT_EQ(7, controller.GetEntryCount());
-  EXPECT_EQ(a_url, controller.GetEntryAtIndex(1)->GetURL());
-  EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui());
-
-  EXPECT_EQ(a1_url, controller.GetEntryAtIndex(2)->GetURL());
-  EXPECT_TRUE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui());
-
-  EXPECT_EQ(a2_url, controller.GetEntryAtIndex(3)->GetURL());
-  EXPECT_TRUE(controller.GetEntryAtIndex(3)->should_skip_on_back_forward_ui());
-
-  EXPECT_EQ(y_url, controller.GetEntryAtIndex(4)->GetURL());
-  EXPECT_FALSE(controller.GetEntryAtIndex(4)->should_skip_on_back_forward_ui());
-
-  EXPECT_EQ(a4_url, controller.GetEntryAtIndex(5)->GetURL());
-  EXPECT_TRUE(controller.GetEntryAtIndex(5)->should_skip_on_back_forward_ui());
-
-  EXPECT_EQ(c_url, controller.GetEntryAtIndex(6)->GetURL());
-  EXPECT_FALSE(controller.GetEntryAtIndex(6)->should_skip_on_back_forward_ui());
-
-  // Go back should skip all A entries and go to Y.
-  {
-    TestNavigationObserver load_observer(shell()->web_contents());
-    controller.GoBack();
-    load_observer.Wait();
-  }
-  EXPECT_EQ(y_url, controller.GetLastCommittedEntry()->GetURL());
-
-  // Going back again should skip all A entries and go to Z.
-  {
-    TestNavigationObserver load_observer(shell()->web_contents());
-    controller.GoBack();
-    load_observer.Wait();
-  }
-  EXPECT_EQ(z_url, controller.GetLastCommittedEntry()->GetURL());
-}
-
 // Tests that a same document navigation followed by a client redirect
 // do not add any more session history entries and going to previous entry
 // works.
@@ -18876,7 +17550,6 @@
 class SandboxedNavigationControllerBrowserTest
     : public NavigationControllerBrowserTest {
  protected:
-
   void SetupNavigation() {
     NavigationControllerImpl& controller =
         static_cast<NavigationControllerImpl&>(
@@ -19036,7 +17709,6 @@
 class SandboxedNavigationControllerPopupBrowserTest
     : public NavigationControllerBrowserTest {
  protected:
-
   void SetupNavigation() {
     EXPECT_EQ(1u, Shell::windows().size());
     NavigationControllerImpl& controller =
@@ -23113,7 +21785,7 @@
     EXPECT_FALSE(webui_nav->HasRenderFrameHost());
     EXPECT_TRUE(webui_nav->HasWebUI());
     created_webui = webui_nav->web_ui();
-    EXPECT_FALSE(created_webui->has_frame_host());
+    EXPECT_FALSE(created_webui->HasRenderFrameHost());
 
     // The pending commit RenderFrameHost for `url_2` is still around and
     // doesn't have a WebUI Object.
@@ -23151,8 +21823,9 @@
   EXPECT_TRUE(webui_nav->HasRenderFrameHost());
   EXPECT_FALSE(webui_nav->HasWebUI());
   EXPECT_EQ(created_webui, webui_nav->GetRenderFrameHost()->web_ui());
-  EXPECT_TRUE(created_webui->has_frame_host());
-  EXPECT_EQ(created_webui->frame_host(), webui_nav->GetRenderFrameHost());
+  EXPECT_TRUE(created_webui->HasRenderFrameHost());
+  EXPECT_EQ(created_webui->GetRenderFrameHost(),
+            webui_nav->GetRenderFrameHost());
   EXPECT_EQ(webui_nav->GetRenderFrameHost(),
             root->render_manager()->speculative_frame_host());
 
@@ -23162,7 +21835,7 @@
   EXPECT_TRUE(webui_nav_manager.was_successful());
   EXPECT_EQ(url_webui, contents()->GetLastCommittedURL());
   EXPECT_EQ(created_webui, current_main_frame_host()->web_ui());
-  EXPECT_EQ(created_webui->frame_host(), current_main_frame_host());
+  EXPECT_EQ(created_webui->GetRenderFrameHost(), current_main_frame_host());
 }
 
 INSTANTIATE_TEST_SUITE_P(
@@ -23185,18 +21858,6 @@
     NavigationControllerBrowserTest::DescribeParams);
 INSTANTIATE_TEST_SUITE_P(
     All,
-    NavigationControllerDebugHistoryInterventionNoUserActivation,
-    testing::Combine(testing::ValuesIn(RenderDocumentFeatureLevelValues()),
-                     testing::Bool()),
-    NavigationControllerBrowserTest::DescribeParams);
-INSTANTIATE_TEST_SUITE_P(
-    All,
-    NavigationControllerHistoryInterventionBrowserTest,
-    testing::Combine(testing::ValuesIn(RenderDocumentFeatureLevelValues()),
-                     testing::Bool()),
-    NavigationControllerBrowserTest::DescribeParams);
-INSTANTIATE_TEST_SUITE_P(
-    All,
     NavigationControllerMainDocumentSequenceNumberBrowserTest,
     testing::Combine(testing::ValuesIn(RenderDocumentFeatureLevelValues()),
                      testing::Bool()),
diff --git a/content/browser/renderer_host/navigation_entry_impl.cc b/content/browser/renderer_host/navigation_entry_impl.cc
index 1e15ec2..ab6e19a 100644
--- a/content/browser/renderer_host/navigation_entry_impl.cc
+++ b/content/browser/renderer_host/navigation_entry_impl.cc
@@ -89,9 +89,16 @@
 
   if (!entry) {
     absl::optional<GURL> initiator_base_url;
-    if (state.initiator_base_url_string) {
-      initiator_base_url =
+    if (blink::features::IsNewBaseUrlInheritanceBehaviorEnabled() &&
+        state.initiator_base_url_string) {
+      GURL initiator_base_url_from_state =
           GURL(UTF16ToUTF8(state.initiator_base_url_string.value()));
+      if (!initiator_base_url_from_state.is_empty()) {
+        // TODO(crbug.com/1356658): refactor the uses of
+        // `state.initiator_base_url_string` so they store nullopt instead of
+        // empty strings.
+        initiator_base_url = initiator_base_url_from_state;
+      }
     }
     entry = base::MakeRefCounted<FrameNavigationEntry>(
         UTF16ToUTF8(state.target.value_or(std::u16string())),
diff --git a/content/browser/renderer_host/render_frame_host_manager.cc b/content/browser/renderer_host/render_frame_host_manager.cc
index 33467ce..b51154d 100644
--- a/content/browser/renderer_host/render_frame_host_manager.cc
+++ b/content/browser/renderer_host/render_frame_host_manager.cc
@@ -1547,7 +1547,7 @@
     // It's possible for the navigation to already have a WebUI associated with
     // it if this function is called from OnResponseStarted.
     CHECK_GE(request->state(), NavigationRequest::WILL_PROCESS_RESPONSE);
-    CHECK(!request->web_ui()->has_frame_host());
+    CHECK(!request->web_ui()->HasRenderFrameHost());
     return;
   }
 
diff --git a/content/browser/renderer_host/render_frame_metadata_provider_impl.cc b/content/browser/renderer_host/render_frame_metadata_provider_impl.cc
index 035df5f..2a39143 100644
--- a/content/browser/renderer_host/render_frame_metadata_provider_impl.cc
+++ b/content/browser/renderer_host/render_frame_metadata_provider_impl.cc
@@ -12,6 +12,11 @@
 #include "build/build_config.h"
 #include "content/browser/renderer_host/frame_token_message_queue.h"
 
+#if BUILDFLAG(IS_ANDROID)
+#include "base/android/jni_android.h"
+#include "content/public/android/content_jni_headers/RenderFrameMetadataProviderImpl_jni.h"
+#endif
+
 namespace content {
 
 RenderFrameMetadataProviderImpl::RenderFrameMetadataProviderImpl(
@@ -21,7 +26,12 @@
       frame_token_message_queue_(frame_token_message_queue) {}
 
 RenderFrameMetadataProviderImpl::~RenderFrameMetadataProviderImpl() {
-  CHECK(!inside_metadata_changed_);
+  if (inside_metadata_changed_) {
+#if BUILDFLAG(IS_ANDROID)
+    JNIEnv* env = base::android::AttachCurrentThread();
+    android::Java_RenderFrameMetadataProviderImpl_reportRecursiveDelete(env);
+#endif
+  }
 }
 
 void RenderFrameMetadataProviderImpl::AddObserver(Observer* observer) {
@@ -113,13 +123,26 @@
     const cc::RenderFrameMetadata& metadata) {
   base::AutoReset<bool> auto_reset(&inside_metadata_changed_, true);
 
-  for (Observer& observer : observers_)
+  // Guard for this being recursively deleted from one of the observer
+  // callbacks.
+  base::WeakPtr<RenderFrameMetadataProviderImpl> self =
+      weak_factory_.GetWeakPtr();
+
+  for (Observer& observer : observers_) {
     observer.OnRenderFrameMetadataChangedBeforeActivation(metadata);
+    if (!self) {
+      return;
+    }
+  }
 
   if (metadata.local_surface_id != last_local_surface_id_) {
     last_local_surface_id_ = metadata.local_surface_id;
-    for (Observer& observer : observers_)
+    for (Observer& observer : observers_) {
       observer.OnLocalSurfaceIdChanged(metadata);
+      if (!self) {
+        return;
+      }
+    }
   }
 
   if (!frame_token)
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 44fecf2..a2d47ff 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -3224,7 +3224,7 @@
 
 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) {
   command_line->AppendSwitchASCII(
-      blink::switches::kNumRasterThreads,
+      cc::switches::kNumRasterThreads,
       base::NumberToString(NumberOfRendererRasterThreads()));
 
   int msaa_sample_count = GpuRasterizationMSAASampleCount();
diff --git a/content/browser/renderer_host/unassigned_site_instance_browsertest.cc b/content/browser/renderer_host/unassigned_site_instance_browsertest.cc
index 07042f3..32763fe 100644
--- a/content/browser/renderer_host/unassigned_site_instance_browsertest.cc
+++ b/content/browser/renderer_host/unassigned_site_instance_browsertest.cc
@@ -60,22 +60,7 @@
 namespace content {
 
 namespace {
-
 const std::string kEmptySchemeForTesting = "empty-scheme";
-
-void InitBackForwardCacheFeature(base::test::ScopedFeatureList* feature_list,
-                                 bool enable_back_forward_cache) {
-  if (enable_back_forward_cache) {
-    feature_list->InitWithFeaturesAndParameters(
-        GetBasicBackForwardCacheFeatureForTesting(
-            {{kBackForwardCacheNoTimeEviction, {}},
-             {features::kBackForwardCacheMemoryControls, {}}}),
-        {});
-  } else {
-    feature_list->InitAndDisableFeature(features::kBackForwardCache);
-  }
-}
-
 }  // namespace
 
 // Note that this test suite is parametrized for RenderDocument and
diff --git a/content/browser/shared_storage/shared_storage_document_service_impl.cc b/content/browser/shared_storage/shared_storage_document_service_impl.cc
index 41e05c6e..2e67d12 100644
--- a/content/browser/shared_storage/shared_storage_document_service_impl.cc
+++ b/content/browser/shared_storage/shared_storage_document_service_impl.cc
@@ -15,6 +15,7 @@
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/common/content_client.h"
+#include "services/network/public/cpp/is_potentially_trustworthy.h"
 #include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/common/shared_storage/shared_storage_utils.h"
 #include "url/url_constants.h"
@@ -23,6 +24,18 @@
 
 namespace {
 
+// TODO(yaoxia): This should be function in FrameTreeNode.
+bool IsSecureFrame(RenderFrameHost* frame) {
+  while (frame) {
+    if (!network::IsOriginPotentiallyTrustworthy(
+            frame->GetLastCommittedOrigin())) {
+      return false;
+    }
+    frame = frame->GetParent();
+  }
+  return true;
+}
+
 using AccessType =
     SharedStorageWorkletHostManager::SharedStorageObserverInterface::AccessType;
 
@@ -69,6 +82,14 @@
   CHECK(!receiver_)
       << "Multiple attempts to bind the SharedStorageDocumentService receiver";
 
+  if (!IsSecureFrame(&render_frame_host())) {
+    // This could indicate a compromised renderer, so let's terminate it.
+    mojo::ReportBadMessage(
+        "Attempted to request SharedStorageDocumentService from an insecure "
+        "context");
+    return;
+  }
+
   receiver_.Bind(std::move(receiver));
 }
 
diff --git a/content/browser/webui/test_webui_js_bridge_ui.h b/content/browser/webui/test_webui_js_bridge_ui.h
index 77cc0ecf..2eca36ae 100644
--- a/content/browser/webui/test_webui_js_bridge_ui.h
+++ b/content/browser/webui/test_webui_js_bridge_ui.h
@@ -12,7 +12,7 @@
 // WebUIController for WebUIJsBridge unittests.
 class TestWebUIJsBridgeUI : public WebUIController {
  public:
-  explicit TestWebUIJsBridgeUI() : WebUIController(nullptr) {}
+  explicit TestWebUIJsBridgeUI(WebUI* web_ui) : WebUIController(web_ui) {}
   ~TestWebUIJsBridgeUI() override = default;
 
   TestWebUIJsBridgeUI(const TestWebUIJsBridgeUI&) = delete;
@@ -24,7 +24,8 @@
 // WebUIController for WebUIJsBridge unittests.
 class TestWebUIJsBridgeIncorrectUI : public WebUIController {
  public:
-  explicit TestWebUIJsBridgeIncorrectUI() : WebUIController(nullptr) {}
+  explicit TestWebUIJsBridgeIncorrectUI(WebUI* web_ui)
+      : WebUIController(web_ui) {}
   ~TestWebUIJsBridgeIncorrectUI() override = default;
 
   TestWebUIJsBridgeIncorrectUI(const TestWebUIJsBridgeIncorrectUI&) = delete;
diff --git a/content/browser/webui/web_ui_browsertest.cc b/content/browser/webui/web_ui_browsertest.cc
index 8c0d9aa..f9f895ec4 100644
--- a/content/browser/webui/web_ui_browsertest.cc
+++ b/content/browser/webui/web_ui_browsertest.cc
@@ -420,10 +420,10 @@
   web_contents->GetWebUI()->AddMessageHandler(base::WrapUnique(test_handler));
 
   auto* webui = static_cast<WebUIImpl*>(web_contents->GetWebUI());
-  EXPECT_EQ(web_contents->GetPrimaryMainFrame(), webui->frame_host());
+  EXPECT_EQ(web_contents->GetPrimaryMainFrame(), webui->GetRenderFrameHost());
 
   test_handler->set_finish_closure(base::BindLambdaForTesting([&]() {
-    EXPECT_NE(web_contents->GetPrimaryMainFrame(), webui->frame_host());
+    EXPECT_NE(web_contents->GetPrimaryMainFrame(), webui->GetRenderFrameHost());
   }));
 
   bool received_send_message = false;
diff --git a/content/browser/webui/web_ui_impl.cc b/content/browser/webui/web_ui_impl.cc
index b1c20e87..ab3aad4 100644
--- a/content/browser/webui/web_ui_impl.cc
+++ b/content/browser/webui/web_ui_impl.cc
@@ -116,7 +116,8 @@
 }
 
 void WebUIImpl::SetRenderFrameHost(RenderFrameHost* render_frame_host) {
-  frame_host_ = static_cast<RenderFrameHostImpl*>(render_frame_host);
+  frame_host_ =
+      static_cast<RenderFrameHostImpl*>(render_frame_host)->GetWeakPtr();
   // Assert that we can only open WebUI for the active or speculative pages.
   DCHECK(frame_host_->lifecycle_state() ==
              RenderFrameHostImpl::LifecycleStateImpl::kActive ||
@@ -201,6 +202,14 @@
   return controller_.get();
 }
 
+RenderFrameHost* WebUIImpl::GetRenderFrameHost() {
+  return frame_host_.get();
+}
+
+bool WebUIImpl::HasRenderFrameHost() const {
+  return !!frame_host_;
+}
+
 void WebUIImpl::SetController(std::unique_ptr<WebUIController> controller) {
   DCHECK(controller);
   controller_ = std::move(controller);
diff --git a/content/browser/webui/web_ui_impl.h b/content/browser/webui/web_ui_impl.h
index fd831f7..2cabbca 100644
--- a/content/browser/webui/web_ui_impl.h
+++ b/content/browser/webui/web_ui_impl.h
@@ -70,6 +70,7 @@
   // WebUI implementation:
   WebContents* GetWebContents() override;
   WebUIController* GetController() override;
+  RenderFrameHost* GetRenderFrameHost() override;
   void SetController(std::unique_ptr<WebUIController> controller) override;
   float GetDeviceScaleFactor() override;
   const std::u16string& GetOverriddenTitle() override;
@@ -99,12 +100,7 @@
     return web_contents_observer_.get();
   }
 
-  RenderFrameHostImpl* frame_host() const {
-    CHECK(frame_host_);
-    return frame_host_;
-  }
-
-  bool has_frame_host() const { return !!frame_host_; }
+  bool HasRenderFrameHost() const;
 
  private:
   friend class WebUIMainFrameObserver;
@@ -140,13 +136,17 @@
   // See regression test:
   // `WebUIImplBrowserTest::SynchronousWebContentDeletionInUnload`
   raw_ptr<WebContents, DisableDanglingPtrDetection> web_contents_;
-  // `frame_host_` might stay unset for a while, as the WebUIImpl object is
-  // created early in a navigation, and a RenderFrameHost for the navigation
-  // might not be created until the final response for the navigation is
-  // received in some cases (after `NavigationRequest::OnResponseStarted()`).
-  // See also `SetRenderFrameHost()` for more details.
-  raw_ptr<RenderFrameHostImpl, DisableDanglingPtrDetection> frame_host_ =
-      nullptr;
+
+  // During WebUI construction, `frame_host_` might stay unset for a while,
+  // as the WebUIImpl object is created early in a navigation, and a
+  // RenderFrameHost for the navigation might not be created until the final
+  // response for the navigation is received in some cases
+  // (after `NavigationRequest::OnResponseStarted()`).
+  // During WebUI destruction, `frame_host_` is always valid except
+  // if the WebContents is destroyed by the WebUIController subclass.
+  // See regression test:
+  // `WebUIImplBrowserTest::SynchronousWebContentDeletionInUnload`
+  base::WeakPtr<RenderFrameHostImpl> frame_host_;
 
   // The WebUIMessageHandlers we own.
   std::vector<std::unique_ptr<WebUIMessageHandler>> handlers_;
diff --git a/content/browser/webui/web_ui_main_frame_observer.cc b/content/browser/webui/web_ui_main_frame_observer.cc
index 7731427..5d2bbc18 100644
--- a/content/browser/webui/web_ui_main_frame_observer.cc
+++ b/content/browser/webui/web_ui_main_frame_observer.cc
@@ -82,7 +82,7 @@
   // Some WebUI pages have another WebUI page in an <iframe>. Both
   // WebUIMainFrameObservers will get a callback when either page gets an error.
   // To avoid duplicates, only report on errors from this page's frame.
-  if (source_frame != web_ui_->frame_host()) {
+  if (source_frame != web_ui_->GetRenderFrameHost()) {
     DVLOG(3) << "Message not reported, different frame";
     return;
   }
@@ -145,7 +145,8 @@
   // https://crbug.com/1154866).
   if (error_reporting_enabled_) {
     DVLOG(3) << "Enabled";
-    web_ui_->frame_host()->SetWantErrorMessageStackTrace();
+    static_cast<content::RenderFrameHostImpl*>(web_ui_->GetRenderFrameHost())
+        ->SetWantErrorMessageStackTrace();
   } else {
     DVLOG(3) << "Error reporting disabled for this page";
   }
@@ -156,10 +157,13 @@
 void WebUIMainFrameObserver::ReadyToCommitNavigation(
     NavigationHandle* navigation_handle) {
   // Navigation didn't occur in the frame associated with this WebUI.
-  if (navigation_handle->GetRenderFrameHost() != web_ui_->frame_host())
+  if (navigation_handle->GetRenderFrameHost() !=
+      web_ui_->GetRenderFrameHost()) {
     return;
+  }
 
-  web_ui_->GetController()->WebUIReadyToCommitNavigation(web_ui_->frame_host());
+  web_ui_->GetController()->WebUIReadyToCommitNavigation(
+      web_ui_->GetRenderFrameHost());
 
 // TODO(crbug.com/1129544) This is currently disabled due to Windows DLL
 // thunking issues. Fix & re-enable.
diff --git a/content/browser/webui/web_ui_main_frame_observer_unittest.cc b/content/browser/webui/web_ui_main_frame_observer_unittest.cc
index 2b547db..7acfab6 100644
--- a/content/browser/webui/web_ui_main_frame_observer_unittest.cc
+++ b/content/browser/webui/web_ui_main_frame_observer_unittest.cc
@@ -183,7 +183,7 @@
 
 TEST_F(WebUIMainFrameObserverTest, ErrorReported) {
   NavigateToPage();
-  CallOnDidAddMessageToConsole(web_ui_->frame_host(),
+  CallOnDidAddMessageToConsole(web_ui_->GetRenderFrameHost(),
                                blink::mojom::ConsoleMessageLevel::kError,
                                kMessage16, 5, kSourceURL16, kStackTrace16);
   task_environment()->RunUntilIdle();
@@ -206,7 +206,7 @@
 
 TEST_F(WebUIMainFrameObserverTest, NoStackTrace) {
   NavigateToPage();
-  CallOnDidAddMessageToConsole(web_ui_->frame_host(),
+  CallOnDidAddMessageToConsole(web_ui_->GetRenderFrameHost(),
                                blink::mojom::ConsoleMessageLevel::kError,
                                kMessage16, 5, kSourceURL16, absl::nullopt);
   task_environment()->RunUntilIdle();
@@ -216,13 +216,13 @@
 
 TEST_F(WebUIMainFrameObserverTest, NonErrorsIgnored) {
   NavigateToPage();
-  CallOnDidAddMessageToConsole(web_ui_->frame_host(),
+  CallOnDidAddMessageToConsole(web_ui_->GetRenderFrameHost(),
                                blink::mojom::ConsoleMessageLevel::kWarning,
                                kMessage16, 5, kSourceURL16, kStackTrace16);
-  CallOnDidAddMessageToConsole(web_ui_->frame_host(),
+  CallOnDidAddMessageToConsole(web_ui_->GetRenderFrameHost(),
                                blink::mojom::ConsoleMessageLevel::kInfo,
                                kMessage16, 5, kSourceURL16, kStackTrace16);
-  CallOnDidAddMessageToConsole(web_ui_->frame_host(),
+  CallOnDidAddMessageToConsole(web_ui_->GetRenderFrameHost(),
                                blink::mojom::ConsoleMessageLevel::kVerbose,
                                kMessage16, 5, kSourceURL16, kStackTrace16);
   task_environment()->RunUntilIdle();
@@ -232,7 +232,7 @@
 TEST_F(WebUIMainFrameObserverTest, NoProcessorDoesntCrash) {
   NavigateToPage();
   FakeJsErrorReportProcessor::SetDefault(nullptr);
-  CallOnDidAddMessageToConsole(web_ui_->frame_host(),
+  CallOnDidAddMessageToConsole(web_ui_->GetRenderFrameHost(),
                                blink::mojom::ConsoleMessageLevel::kError,
                                kMessage16, 5, kSourceURL16, kStackTrace16);
   task_environment()->RunUntilIdle();
@@ -240,7 +240,7 @@
 
 TEST_F(WebUIMainFrameObserverTest, NotSentIfInvalidURL) {
   NavigateToPage();
-  CallOnDidAddMessageToConsole(web_ui_->frame_host(),
+  CallOnDidAddMessageToConsole(web_ui_->GetRenderFrameHost(),
                                blink::mojom::ConsoleMessageLevel::kError,
                                kMessage16, 5, u"invalid URL", kStackTrace16);
   task_environment()->RunUntilIdle();
@@ -251,7 +251,7 @@
   static_cast<MockWebUIController*>(web_ui_->GetController())
       ->enable_javascript_error_reporting(false);
   NavigateToPage();
-  CallOnDidAddMessageToConsole(web_ui_->frame_host(),
+  CallOnDidAddMessageToConsole(web_ui_->GetRenderFrameHost(),
                                blink::mojom::ConsoleMessageLevel::kError,
                                kMessage16, 5, kSourceURL16, kStackTrace16);
   task_environment()->RunUntilIdle();
@@ -290,7 +290,7 @@
 
   for (const URLTest& test : kTests) {
     int previous_count = processor_->error_report_count();
-    CallOnDidAddMessageToConsole(web_ui_->frame_host(),
+    CallOnDidAddMessageToConsole(web_ui_->GetRenderFrameHost(),
                                  blink::mojom::ConsoleMessageLevel::kError,
                                  kMessage16, 5, test.input, kStackTrace16);
     task_environment()->RunUntilIdle();
@@ -306,7 +306,7 @@
       "chrome://bookmarks/add?q=chromium#code";
   NavigationSimulator::NavigateAndCommitFromBrowser(
       web_contents(), GURL(kPageWithQueryAndFragment));
-  CallOnDidAddMessageToConsole(web_ui_->frame_host(),
+  CallOnDidAddMessageToConsole(web_ui_->GetRenderFrameHost(),
                                blink::mojom::ConsoleMessageLevel::kError,
                                kMessage16, 5, kSourceURL16, kStackTrace16);
   task_environment()->RunUntilIdle();
@@ -336,7 +336,7 @@
   };
 
   for (const auto* url : kNonChromeSourceURLs) {
-    CallOnDidAddMessageToConsole(web_ui_->frame_host(),
+    CallOnDidAddMessageToConsole(web_ui_->GetRenderFrameHost(),
                                  blink::mojom::ConsoleMessageLevel::kError,
                                  kMessage16, 5, url, kStackTrace16);
     task_environment()->RunUntilIdle();
diff --git a/content/browser/webui/web_ui_managed_interface.cc b/content/browser/webui/web_ui_managed_interface.cc
new file mode 100644
index 0000000..e27baf8
--- /dev/null
+++ b/content/browser/webui/web_ui_managed_interface.cc
@@ -0,0 +1,58 @@
+// 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/webui/web_ui_managed_interface.h"
+
+#include <vector>
+
+#include "content/browser/renderer_host/render_frame_host_impl.h"
+#include "content/browser/webui/web_ui_impl.h"
+#include "content/public/browser/document_user_data.h"
+#include "content/public/browser/navigation_handle.h"
+#include "content/public/browser/web_ui.h"
+
+namespace content {
+
+namespace internal {
+
+class WebUIManagedInterfaceStorage
+    : public DocumentUserData<WebUIManagedInterfaceStorage> {
+ public:
+  ~WebUIManagedInterfaceStorage() override = default;
+
+  void AddInterfaceImpl(std::unique_ptr<WebUIManagedInterfaceBase> impl) {
+    impls_.push_back(std::move(impl));
+  }
+
+ private:
+  explicit WebUIManagedInterfaceStorage(RenderFrameHost* render_frame_host)
+      : DocumentUserData<WebUIManagedInterfaceStorage>(render_frame_host) {}
+
+  friend DocumentUserData;
+  DOCUMENT_USER_DATA_KEY_DECL();
+
+  std::vector<std::unique_ptr<WebUIManagedInterfaceBase>> impls_;
+};
+
+DOCUMENT_USER_DATA_KEY_IMPL(WebUIManagedInterfaceStorage);
+
+void SaveWebUIManagedInterfaceInDocument(
+    WebUIController* controller,
+    std::unique_ptr<WebUIManagedInterfaceBase> data) {
+  auto* storage = WebUIManagedInterfaceStorage::GetOrCreateForCurrentDocument(
+      controller->web_ui()->GetRenderFrameHost());
+  storage->AddInterfaceImpl(std::move(data));
+}
+
+}  // namespace internal
+
+void RemoveWebUIManagedInterfaces(WebUIController* webui_controller) {
+  RenderFrameHost* rfh = webui_controller->web_ui()->GetRenderFrameHost();
+  if (rfh &&
+      internal::WebUIManagedInterfaceStorage::GetForCurrentDocument(rfh)) {
+    internal::WebUIManagedInterfaceStorage::DeleteForCurrentDocument(rfh);
+  }
+}
+
+}  // namespace content
diff --git a/content/browser/webui/web_ui_managed_interface.h b/content/browser/webui/web_ui_managed_interface.h
new file mode 100644
index 0000000..7f01e7ca
--- /dev/null
+++ b/content/browser/webui/web_ui_managed_interface.h
@@ -0,0 +1,202 @@
+// 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_WEBUI_WEB_UI_MANAGED_INTERFACE_H_
+#define CONTENT_BROWSER_WEBUI_WEB_UI_MANAGED_INTERFACE_H_
+
+#include <memory>
+#include <utility>
+
+#include "base/memory/raw_ptr.h"
+#include "base/supports_user_data.h"
+#include "content/common/content_export.h"
+#include "content/public/browser/web_ui_controller.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/remote.h"
+
+namespace content {
+
+CONTENT_EXPORT void RemoveWebUIManagedInterfaces(
+    WebUIController* webui_controller);
+
+namespace internal {
+
+class CONTENT_EXPORT WebUIManagedInterfaceBase {
+ public:
+  virtual ~WebUIManagedInterfaceBase() = default;
+};
+
+// Stores an interface implementation instance in the WebUI host Document.
+// This is called when constructing an implementation instance in
+// WebUIManagedInterface::Create().
+void CONTENT_EXPORT
+SaveWebUIManagedInterfaceInDocument(content::WebUIController*,
+                                    std::unique_ptr<WebUIManagedInterfaceBase>);
+
+}  // namespace internal
+
+// WebUIManagedInterface is an optional base class for implementing classes
+// that interact with Mojo endpoints e.g. implement a Mojo interface or
+// communicate with a Mojo Remote.
+//
+// This class provides automated handling of Mojo endpoint bindings and
+// lifetime management. The subclass object is created when Create() is
+// called and destroyed when the associated WebUI document is removed or
+// navigates away.
+//
+// To implement interface Foo, use the following code:
+//   class FooImpl : public WebUIManagedInterface<FooImpl, Foo> { ... }
+//
+// Additionally, to communiate with remote interface Bar:
+//   class FooBarImpl : public WebUIManagedInterface<FooBarImpl, Foo, Bar> { ...
+//   }
+//
+// To implement no interface but only communicate with a remote interface:
+//   class Baz : public WebUIManagedInterface<
+//                            Baz,
+//                            WebUIManagedInterfaceNoPageHandler,
+//                            BarObserver> { ... }
+//
+// TODO(crbug.com/1417272): provide helpers to retrieve InterfaceImpl objects.
+template <typename InterfaceImpl, typename... Interfaces>
+class WebUIManagedInterface;
+
+template <typename InterfaceImpl, typename PageHandler, typename Page>
+class WebUIManagedInterface<InterfaceImpl, PageHandler, Page>
+    : public PageHandler, public internal::WebUIManagedInterfaceBase {
+ public:
+  static void Create(content::WebUIController*,
+                     mojo::PendingReceiver<PageHandler>,
+                     mojo::PendingRemote<Page>);
+
+  // Invoked when Mojo endpoints are bound and ready to use.
+  // TODO(crbug.com/1417260): Remove this by saving endpoints in an external
+  // storage before constructing `InterfaceImpl`.
+  virtual void OnReady() {}
+
+  mojo::Receiver<PageHandler>& receiver() {
+    CHECK(ready_) << "Mojo endpoints are not ready. Please use OnReady().";
+    return page_handler_receiver_;
+  }
+  mojo::Remote<Page>& remote() {
+    CHECK(ready_) << "Mojo endpoints are not ready. Please use OnReady().";
+    return page_remote_;
+  }
+  content::WebUIController* webui_controller() {
+    CHECK(ready_) << "webui_controller() is not ready. Please use OnReady().";
+    return webui_controller_;
+  }
+
+ private:
+  bool ready_ = false;
+  mojo::Receiver<PageHandler> page_handler_receiver_{this};
+  mojo::Remote<Page> page_remote_;
+  raw_ptr<content::WebUIController> webui_controller_;
+};
+
+template <typename InterfaceImpl, typename PageHandler>
+class WebUIManagedInterface<InterfaceImpl, PageHandler>
+    : public PageHandler, public internal::WebUIManagedInterfaceBase {
+ public:
+  static void Create(content::WebUIController*,
+                     mojo::PendingReceiver<PageHandler>);
+
+  // Invoked when Mojo endpoints are bound and ready to use.
+  // TODO(crbug.com/1417260): Remove this by saving endpoints in an external
+  // storage before constructing `InterfaceImpl`.
+  virtual void OnReady() {}
+
+  mojo::Receiver<PageHandler>& receiver() {
+    CHECK(ready_) << "Mojo endpoints are not ready. Please use OnReady().";
+    return page_handler_receiver_;
+  }
+  content::WebUIController* webui_controller() {
+    CHECK(ready_) << "webui_controller() is not ready. Please use OnReady().";
+    return webui_controller_;
+  }
+
+ private:
+  bool ready_ = false;
+  mojo::Receiver<PageHandler> page_handler_receiver_{this};
+  raw_ptr<content::WebUIController> webui_controller_;
+};
+
+using WebUIManagedInterfaceNoPageHandler = void;
+
+template <typename InterfaceImpl, typename Page>
+class WebUIManagedInterface<InterfaceImpl,
+                            WebUIManagedInterfaceNoPageHandler,
+                            Page> : public internal::WebUIManagedInterfaceBase {
+ public:
+  static void Create(content::WebUIController*, mojo::PendingRemote<Page>);
+
+  // Invoked when Mojo endpoints are bound and ready to use.
+  // TODO(crbug.com/1417260): Remove this by saving endpoints in an external
+  // storage before constructing `InterfaceImpl`.
+  virtual void OnReady() {}
+
+  mojo::Remote<Page>& remote() {
+    CHECK(ready_) << "Mojo endpoints are not ready. Please use OnReady().";
+    return page_remote_;
+  }
+  content::WebUIController* webui_controller() {
+    CHECK(ready_) << "webui_controller() is not ready. Please use OnReady().";
+    return webui_controller_;
+  }
+
+ private:
+  bool ready_ = false;
+  mojo::Remote<Page> page_remote_;
+  raw_ptr<content::WebUIController> webui_controller_;
+};
+
+template <typename InterfaceImpl, typename PageHandler, typename Page>
+void WebUIManagedInterface<InterfaceImpl, PageHandler, Page>::Create(
+    content::WebUIController* webui_controller,
+    mojo::PendingReceiver<PageHandler> pending_receiver,
+    mojo::PendingRemote<Page> pending_remote) {
+  auto interface_impl = std::make_unique<InterfaceImpl>();
+  auto* interface_impl_ptr = interface_impl.get();
+  interface_impl->webui_controller_ = webui_controller;
+  interface_impl->page_handler_receiver_.Bind(std::move(pending_receiver));
+  interface_impl->page_remote_.Bind(std::move(pending_remote));
+  internal::SaveWebUIManagedInterfaceInDocument(webui_controller,
+                                                std::move(interface_impl));
+  interface_impl_ptr->ready_ = true;
+  interface_impl_ptr->OnReady();
+}
+
+template <typename InterfaceImpl, typename PageHandler>
+void WebUIManagedInterface<InterfaceImpl, PageHandler>::Create(
+    content::WebUIController* webui_controller,
+    mojo::PendingReceiver<PageHandler> pending_receiver) {
+  auto interface_impl = std::make_unique<InterfaceImpl>();
+  auto* interface_impl_ptr = interface_impl.get();
+  interface_impl->webui_controller_ = webui_controller;
+  interface_impl->page_handler_receiver_.Bind(std::move(pending_receiver));
+  internal::SaveWebUIManagedInterfaceInDocument(webui_controller,
+                                                std::move(interface_impl));
+  interface_impl_ptr->ready_ = true;
+  interface_impl_ptr->OnReady();
+}
+
+template <typename InterfaceImpl, typename Page>
+void WebUIManagedInterface<InterfaceImpl, void, Page>::Create(
+    content::WebUIController* webui_controller,
+    mojo::PendingRemote<Page> pending_remote) {
+  auto interface_impl = std::make_unique<InterfaceImpl>();
+  auto* interface_impl_ptr = interface_impl.get();
+  interface_impl->webui_controller_ = webui_controller;
+  interface_impl->page_remote_.Bind(std::move(pending_remote));
+  internal::SaveWebUIManagedInterfaceInDocument(webui_controller,
+                                                std::move(interface_impl));
+  interface_impl_ptr->ready_ = true;
+  interface_impl_ptr->OnReady();
+}
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_WEBUI_WEB_UI_MANAGED_INTERFACE_H_
diff --git a/content/browser/webui/web_ui_managed_interface_browsertest.cc b/content/browser/webui/web_ui_managed_interface_browsertest.cc
new file mode 100644
index 0000000..3451834
--- /dev/null
+++ b/content/browser/webui/web_ui_managed_interface_browsertest.cc
@@ -0,0 +1,443 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <memory>
+
+#include "base/functional/callback_forward.h"
+#include "base/path_service.h"
+#include "base/run_loop.h"
+#include "base/strings/strcat.h"
+#include "base/test/bind.h"
+#include "content/browser/webui/web_ui_managed_interface.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/render_process_host_observer.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_ui_browser_interface_broker_registry.h"
+#include "content/public/browser/web_ui_controller_factory.h"
+#include "content/public/browser/web_ui_data_source.h"
+#include "content/public/browser/webui_config_map.h"
+#include "content/public/common/content_client.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/common/url_constants.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_content_browser_client.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/test_navigation_observer.h"
+#include "content/public/test/test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "content/test/data/web_ui_managed_interface_test.test-mojom.h"
+#include "content/test/grit/web_ui_mojo_test_resources.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/webui/untrusted_web_ui_browsertest_util.h"
+#include "url/gurl.h"
+
+namespace content {
+
+namespace {
+
+static constexpr char kFooURL[] = "chrome://foo/";
+static constexpr char kFooInIframeURL[] = "chrome-untrusted://foo/";
+
+static constexpr char kBindFooJs[] =
+    "(async () => {"
+    "  let jsBridgeRemote = window.TestWebUIJsBridge.getRemote();"
+    "  let fooRemote = new FooRemote();"
+    "  jsBridgeRemote.bindFoo(fooRemote.$.bindNewPipeAndPassReceiver());"
+    "  return (await fooRemote.getFoo()).value;"
+    "})()";
+
+// A helper class for counting alive instances of a specific class.
+template <typename Type>
+class InstanceCounter {
+ public:
+  static void Increment() { count_++; }
+  static void Decrement() { count_--; }
+  static int count() { return count_; }
+
+ private:
+  static int count_;
+};
+
+template <typename Type>
+int InstanceCounter<Type>::count_ = 0;
+
+// FooImpl implements Foo.
+class FooImpl : public WebUIManagedInterface<FooImpl, mojom::Foo> {
+ public:
+  FooImpl() { InstanceCounter<FooImpl>::Increment(); }
+
+  ~FooImpl() override { InstanceCounter<FooImpl>::Decrement(); }
+
+  // mojom::Foo:
+  void GetFoo(GetFooCallback callback) override {
+    std::move(callback).Run("foo-success");
+  }
+};
+
+// FooImpl implements Foo and talks to a Bar remote.
+class FooBarImpl
+    : public WebUIManagedInterface<FooBarImpl, mojom::Foo, mojom::Bar> {
+ public:
+  FooBarImpl() { InstanceCounter<FooBarImpl>::Increment(); }
+
+  ~FooBarImpl() override { InstanceCounter<FooBarImpl>::Decrement(); }
+
+  // WebUIManagedInterface:
+  void OnReady() override {
+    remote()->GetBar(base::BindRepeating(
+        [](const std::string& value) { EXPECT_EQ("bar-success", value); }));
+  }
+
+  // mojom::Foo:
+  void GetFoo(GetFooCallback callback) override {
+    std::move(callback).Run("foo-success");
+  }
+};
+
+// Baz talks to a mojom::Baz remote. It does not implement any interfaces.
+class Baz : public WebUIManagedInterface<Baz,
+                                         WebUIManagedInterfaceNoPageHandler,
+                                         mojom::Baz> {
+ public:
+  Baz() { InstanceCounter<Baz>::Increment(); }
+
+  ~Baz() override { InstanceCounter<Baz>::Decrement(); }
+
+  // WebUIManagedInterface:
+  void OnReady() override {
+    remote()->GetBaz(base::BindRepeating(
+        [](const std::string& value) { EXPECT_EQ("baz-success", value); }));
+  }
+};
+
+class WebUIManagedInterfaceTestUI : public WebUIController,
+                                    public mojom::TestWebUIJsBridge {
+ public:
+  explicit WebUIManagedInterfaceTestUI(WebUI* web_ui)
+      : WebUIController(web_ui) {
+    // Allow resources to be loaded for both top-level and embedded WebUIs.
+    // Due to the behavior of URLDataManagerBackend::GetDataSourceFromURL(),
+    // WebUIDataSource::CreateAndAdd() expects "host" as the `source_name` arg
+    // for trusted hosts and "chrome-untrusted://host" for untrusted hosts.
+    for (const auto& host :
+         {GURL(kFooURL).host(), std::string(kFooInIframeURL)}) {
+      WebUIDataSource* data_source = WebUIDataSource::CreateAndAdd(
+          web_ui->GetWebContents()->GetBrowserContext(), host);
+      data_source->SetDefaultResource(IDR_WEB_UI_MANAGED_INTERFACE_TEST_HTML);
+      data_source->AddResourcePath(
+          "web_ui_managed_interface_test.test-mojom-webui.js",
+          IDR_WEB_UI_MANAGED_INTERFACE_TEST_TEST_MOJOM_WEBUI_JS);
+      data_source->AddResourcePath("web_ui_managed_interface_test.js",
+                                   IDR_WEB_UI_MANAGED_INTERFACE_TEST_JS);
+
+      // Allow WebUI to be embedded in an iframe under
+      // chrome-untrusted://test-host.
+      if (host == kFooInIframeURL) {
+        data_source->AddFrameAncestor(GURL("chrome-untrusted://test-host"));
+      }
+    }
+  }
+
+  void BindInterface(mojo::PendingReceiver<mojom::TestWebUIJsBridge> receiver) {
+    js_bridge_receiver_.reset();
+    js_bridge_receiver_.Bind(std::move(receiver));
+  }
+
+  // mojom::TestWebUIJsBridge:
+  void BindFoo(mojo::PendingReceiver<mojom::Foo> foo_receiver) override {
+    FooImpl::Create(this, std::move(foo_receiver));
+  }
+
+  void BindFooBar(mojo::PendingReceiver<mojom::Foo> foo_receiver,
+                  mojo::PendingRemote<mojom::Bar> bar_remote) override {
+    FooBarImpl::Create(this, std::move(foo_receiver), std::move(bar_remote));
+  }
+
+  void BindBaz(mojo::PendingRemote<mojom::Baz> baz_remote) override {
+    Baz::Create(this, std::move(baz_remote));
+  }
+
+  WEB_UI_CONTROLLER_TYPE_DECL();
+
+ private:
+  mojo::Receiver<mojom::TestWebUIJsBridge> js_bridge_receiver_{this};
+};
+
+WEB_UI_CONTROLLER_TYPE_IMPL(WebUIManagedInterfaceTestUI)
+
+// WebUIControllerFactory that serves our TestWebUIController.
+class TestFooWebUIControllerFactory : public WebUIControllerFactory {
+ public:
+  TestFooWebUIControllerFactory() = default;
+
+  std::unique_ptr<WebUIController> CreateWebUIControllerForURL(
+      WebUI* web_ui,
+      const GURL& url) override {
+    if (url::IsSameOriginWith(url, GURL(kFooURL)) ||
+        url::IsSameOriginWith(url, GURL(kFooInIframeURL))) {
+      return std::make_unique<WebUIManagedInterfaceTestUI>(web_ui);
+    }
+
+    return nullptr;
+  }
+
+  WebUI::TypeID GetWebUIType(BrowserContext* browser_context,
+                             const GURL& url) override {
+    if (url::IsSameOriginWith(url, GURL(kFooURL))) {
+      return &kFooURL;
+    }
+
+    if (url::IsSameOriginWith(url, GURL(kFooInIframeURL))) {
+      return &kFooInIframeURL;
+    }
+
+    return WebUI::kNoWebUI;
+  }
+
+  bool UseWebUIForURL(BrowserContext* browser_context,
+                      const GURL& url) override {
+    return GetWebUIType(browser_context, url) != WebUI::kNoWebUI;
+  }
+};
+
+}  // namespace
+
+class WebUIManagedInterfaceBrowserTest : public ContentBrowserTest {
+ public:
+  WebUIManagedInterfaceBrowserTest() {
+    factory_ = std::make_unique<TestFooWebUIControllerFactory>();
+    WebUIControllerFactory::RegisterFactory(factory_.get());
+  }
+
+  void SetUpOnMainThread() override {
+    ContentBrowserTest::SetUpOnMainThread();
+    test_content_browser_client_ = std::make_unique<TestContentBrowserClient>();
+  }
+
+  void TearDownOnMainThread() override { test_content_browser_client_.reset(); }
+
+  // Evaluate `statement` in frame (defaults to main frame), and returns its
+  // result. For convenience, `script` should evaluate to a string, or a promise
+  // that resolves to a string.
+  std::string EvalStatement(const std::string& statement,
+                            content::RenderFrameHost* frame = nullptr) {
+    RenderFrameHost* eval_frame =
+        frame ? frame : ConvertToRenderFrameHost(shell());
+
+    // Use EvalJs to execute the statement
+    auto result =
+        EvalJs(eval_frame, statement, content::EXECUTE_SCRIPT_DEFAULT_OPTIONS,
+               content::ISOLATED_WORLD_ID_GLOBAL);
+
+    EXPECT_TRUE(result.error.empty());
+    return result.value.GetString();
+  }
+
+  void Reload(RenderFrameHost* frame = nullptr) {
+    RenderFrameHost* eval_frame =
+        frame ? frame : ConvertToRenderFrameHost(shell());
+    TestNavigationObserver observer(shell()->web_contents(), 1);
+    EXPECT_TRUE(ExecuteScript(eval_frame, "location.reload()"));
+    observer.Wait();
+  }
+
+ private:
+  class TestContentBrowserClient
+      : public ContentBrowserTestContentBrowserClient {
+   public:
+    TestContentBrowserClient() = default;
+    TestContentBrowserClient(const TestContentBrowserClient&) = delete;
+    TestContentBrowserClient& operator=(const TestContentBrowserClient&) =
+        delete;
+    ~TestContentBrowserClient() override = default;
+
+    void RegisterWebUIInterfaceBrokers(
+        WebUIBrowserInterfaceBrokerRegistry& registry) override {
+      registry.ForWebUI<WebUIManagedInterfaceTestUI>()
+          .Add<mojom::TestWebUIJsBridge>();
+    }
+  };
+
+  std::unique_ptr<TestFooWebUIControllerFactory> factory_;
+  std::unique_ptr<TestContentBrowserClient> test_content_browser_client_;
+};
+
+// Test FooImpl that implements Foo is constructed properly and destroyed on
+// navigation.
+IN_PROC_BROWSER_TEST_F(WebUIManagedInterfaceBrowserTest, Foo) {
+  WebContents* web_contents = shell()->web_contents();
+
+  ASSERT_TRUE(NavigateToURL(web_contents, GURL(kFooURL)));
+
+  EXPECT_EQ("foo-success", EvalStatement(kBindFooJs));
+  EXPECT_EQ(1, InstanceCounter<FooImpl>::count());
+
+  // Navigation will destroy interface impls.
+  Reload();
+  EXPECT_EQ(0, InstanceCounter<FooImpl>::count());
+}
+
+// Test FooBarImpl that implements Foo and talks to the Bar remote is
+// constructed properly and destroyed on navigation.
+IN_PROC_BROWSER_TEST_F(WebUIManagedInterfaceBrowserTest, FooBar) {
+  WebContents* web_contents = shell()->web_contents();
+
+  ASSERT_TRUE(NavigateToURL(web_contents, GURL(kFooURL)));
+
+  EXPECT_EQ("foo-success",
+            EvalStatement(
+                "(async () => {"
+                "  let jsBridgeRemote = window.TestWebUIJsBridge.getRemote();"
+                "  let fooRemote = new FooRemote();"
+                "  let barCallbackRouter = new BarCallbackRouter();"
+                "  let listenerPromise = new Promise(resolve => {"
+                "    barCallbackRouter.getBar.addListener(() => {"
+                "      /* Resolve the promise after the response is sent. */"
+                "      setTimeout(resolve, 0);"
+                "      return { value: 'bar-success' };"
+                "    });"
+                "  });"
+                ""
+                "  jsBridgeRemote.bindFooBar("
+                "    fooRemote.$.bindNewPipeAndPassReceiver(),"
+                "    barCallbackRouter.$.bindNewPipeAndPassRemote());"
+                ""
+                "  /* Wait for the listener to be called. */"
+                "  await listenerPromise;"
+                "  /* Wait for the response to get to the browser. */"
+                "  await barCallbackRouter.$.flush();"
+                ""
+                "  return (await fooRemote.getFoo()).value;"
+                "})()"));
+  EXPECT_EQ(1, InstanceCounter<FooBarImpl>::count());
+
+  // Navigation will destroy interface impls.
+  Reload();
+  EXPECT_EQ(0, InstanceCounter<FooBarImpl>::count());
+}
+
+// Test Baz that talks to the Baz remote is constructed properly and
+// destroyed on navigation.
+IN_PROC_BROWSER_TEST_F(WebUIManagedInterfaceBrowserTest, Baz) {
+  WebContents* web_contents = shell()->web_contents();
+
+  ASSERT_TRUE(NavigateToURL(web_contents, GURL(kFooURL)));
+
+  EXPECT_EQ("success",
+            EvalStatement(
+                "(async () => {"
+                "  let jsBridgeRemote = window.TestWebUIJsBridge.getRemote();"
+                "  let bazCallbackRouter = new BazCallbackRouter();"
+                "  let listenerPromise = new Promise(resolve => {"
+                "    bazCallbackRouter.getBaz.addListener(() => {"
+                "      /* Resolve the promise after the response is sent. */"
+                "      setTimeout(resolve, 0);"
+                "      return { value: 'baz-success' };"
+                "    });"
+                "  });"
+                ""
+                "  jsBridgeRemote.bindBaz("
+                "    bazCallbackRouter.$.bindNewPipeAndPassRemote());"
+                ""
+                "  /* Wait for the listener to be called. */"
+                "  await listenerPromise;"
+                "  /* Wait for the response to get to the browser. */"
+                "  await bazCallbackRouter.$.flush();"
+                ""
+                "  return 'success';"
+                "})()"));
+  EXPECT_EQ(1, InstanceCounter<Baz>::count());
+
+  // Navigation will destroy interface impls.
+  Reload();
+  EXPECT_EQ(0, InstanceCounter<Baz>::count());
+}
+
+// Test that interface impls of an iframe WebUI are destroyed on iframe reload.
+IN_PROC_BROWSER_TEST_F(WebUIManagedInterfaceBrowserTest, WebUIInIframe) {
+  WebContents* web_contents = shell()->web_contents();
+  // Allow adding chrome-untrusted://foo in an iframe.
+  TestUntrustedDataSourceHeaders headers;
+  headers.child_src = "child-src *;";
+  // Use a test host WebUI. We intentionally don't use chrome://foo as the host
+  // WebUI, otherwise there will be two instances of WebUIManagedInterfaceTestUI
+  // while we only care about the embedded one.
+  content::WebUIConfigMap::GetInstance().AddUntrustedWebUIConfig(
+      std::make_unique<ui::TestUntrustedWebUIConfig>("test-host", headers));
+
+  // Load host page.
+  ASSERT_TRUE(NavigateToURL(web_contents,
+                            GetChromeUntrustedUIURL("test-host/title1.html")));
+
+  // Append an iframe that opens chrome-untrusted://foo.
+  EXPECT_EQ(true,
+            EvalJs(web_contents->GetPrimaryMainFrame(),
+                   JsReplace("let frame = document.createElement('iframe');"
+                             "frame.src=$1;"
+                             "!!document.body.appendChild(frame);",
+                             GURL(kFooInIframeURL).spec()),
+                   EXECUTE_SCRIPT_DEFAULT_OPTIONS, 1 /* world_id */));
+  EXPECT_TRUE(WaitForLoadStop(web_contents));
+
+  RenderFrameHost* foo_frame =
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
+  ASSERT_EQ(GURL(kFooInIframeURL), foo_frame->GetLastCommittedURL());
+
+  EXPECT_EQ("foo-success", EvalStatement(kBindFooJs, foo_frame));
+  EXPECT_EQ(1, InstanceCounter<FooImpl>::count());
+
+  // Iframe navigation will destroy interface impls.
+  Reload(foo_frame);
+  EXPECT_EQ(0, InstanceCounter<FooImpl>::count());
+
+  // Interface impls can be created after reload.
+  EXPECT_EQ("foo-success", EvalStatement(kBindFooJs, foo_frame));
+  EXPECT_EQ(1, InstanceCounter<FooImpl>::count());
+}
+
+// Test that interface impls of an iframe WebUI are destroyed on iframe removal.
+IN_PROC_BROWSER_TEST_F(WebUIManagedInterfaceBrowserTest, RemoveIframe) {
+  WebContents* web_contents = shell()->web_contents();
+  // Allow adding chrome-untrusted://foo in an iframe.
+  TestUntrustedDataSourceHeaders headers;
+  headers.child_src = "child-src *;";
+  // Use a test host WebUI. We intentionally don't use chrome://foo as the host
+  // WebUI, otherwise there will be two instances of WebUIManagedInterfaceTestUI
+  // while we only care about the embedded one.
+  content::WebUIConfigMap::GetInstance().AddUntrustedWebUIConfig(
+      std::make_unique<ui::TestUntrustedWebUIConfig>("test-host", headers));
+
+  // Load host page.
+  ASSERT_TRUE(NavigateToURL(web_contents,
+                            GetChromeUntrustedUIURL("test-host/title1.html")));
+
+  // Append an iframe that opens chrome-untrusted://foo.
+  EXPECT_EQ(true,
+            EvalJs(web_contents->GetPrimaryMainFrame(),
+                   JsReplace("let frame = document.createElement('iframe');"
+                             "frame.src=$1;frame.id='untrusted-webui';"
+                             "!!document.body.appendChild(frame);",
+                             GURL(kFooInIframeURL).spec()),
+                   EXECUTE_SCRIPT_DEFAULT_OPTIONS, 1 /* world_id */));
+  EXPECT_TRUE(WaitForLoadStop(web_contents));
+
+  RenderFrameHost* foo_frame =
+      ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
+  ASSERT_EQ(GURL(kFooInIframeURL), foo_frame->GetLastCommittedURL());
+
+  EXPECT_EQ("foo-success", EvalStatement(kBindFooJs, foo_frame));
+  EXPECT_EQ(1, InstanceCounter<FooImpl>::count());
+
+  // Iframe removal will destroy interface impls.
+  RenderFrameDeletedObserver frame_deleted_observer(foo_frame);
+  EXPECT_TRUE(ExecuteScript(
+      shell(), "document.getElementById('untrusted-webui').remove()"));
+  frame_deleted_observer.WaitUntilDeleted();
+  EXPECT_EQ(0, InstanceCounter<FooImpl>::count());
+}
+
+}  // namespace content
diff --git a/content/browser/webui/web_ui_webui_js_bridge_unittest.cc b/content/browser/webui/web_ui_webui_js_bridge_unittest.cc
index 2618d01..71f23146 100644
--- a/content/browser/webui/web_ui_webui_js_bridge_unittest.cc
+++ b/content/browser/webui/web_ui_webui_js_bridge_unittest.cc
@@ -5,6 +5,7 @@
 #include "base/test/bind.h"
 #include "base/test/task_environment.h"
 #include "content/browser/webui/test_webui_js_bridge_ui.h"
+#include "content/public/test/test_web_ui.h"
 #include "content/test/web_ui/webui_js_bridge_unittest.test-mojom-webui-js-bridge-impl.h"
 #include "content/test/web_ui/webui_js_bridge_unittest2.test-mojom-webui-js-bridge-impl.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
@@ -84,8 +85,11 @@
   WebUIJsBridgeTest() = default;
   ~WebUIJsBridgeTest() override = default;
 
+  TestWebUI* web_ui() { return &test_web_ui; }
+
  private:
   base::test::TaskEnvironment task_environment_;
+  TestWebUI test_web_ui;
 };
 
 // Tests binder methods are overridden and can be called. Calling them does
@@ -100,7 +104,7 @@
       });
   Bar bar;
 
-  TestWebUIJsBridgeUI controller;
+  TestWebUIJsBridgeUI controller(web_ui());
   mojom::FooWebUIJsBridgeImpl bridge(
       &controller, page_handler_binder,
       base::BindRepeating(&Bar::BindBar, base::Unretained(&bar)),
@@ -129,7 +133,7 @@
 // Tests we correctly generate a WebUIJsBridgeImpl for a interface that
 // binds interfaces in a separate mojom.
 TEST_F(WebUIJsBridgeTest, CrossModule) {
-  TestWebUIJsBridgeUI controller;
+  TestWebUIJsBridgeUI controller(web_ui());
   mojom::TestWebUIJsBridge2Impl bridge(&controller, base::DoNothing());
   bridge.BindSecondaryInterface(mojo::NullReceiver());
 }
@@ -137,7 +141,7 @@
 // Tests that we crash if the wrong WebUIController is passed to the
 // WebUIJsBridge.
 TEST_F(WebUIJsBridgeTest, IncorrectWebUIControllerCrash) {
-  TestWebUIJsBridgeIncorrectUI controller;
+  TestWebUIJsBridgeIncorrectUI controller(web_ui());
   EXPECT_DEATH_IF_SUPPORTED(
       mojom::TestWebUIJsBridge2Impl bridge(&controller, base::DoNothing()), "");
 }
diff --git a/content/common/mac/attributed_string_type_converters.h b/content/common/mac/attributed_string_type_converters.h
index f29d965..fbb5670 100644
--- a/content/common/mac/attributed_string_type_converters.h
+++ b/content/common/mac/attributed_string_type_converters.h
@@ -9,26 +9,22 @@
 #include "ui/base/mojom/attributed_string.mojom.h"
 #include "ui/gfx/range/range.h"
 
-#if __OBJC__
-@class NSAttributedString;
-#else
-class NSAttributedString;
-#endif
+#include <CoreFoundation/CoreFoundation.h>
 
 namespace mojo {
 
 template <>
 struct CONTENT_EXPORT
-    TypeConverter<NSAttributedString*, ui::mojom::AttributedStringPtr> {
-  static NSAttributedString* Convert(
+    TypeConverter<CFAttributedStringRef, ui::mojom::AttributedStringPtr> {
+  static CFAttributedStringRef Convert(
       const ui::mojom::AttributedStringPtr& mojo_attributed_string);
 };
 
 template <>
 struct CONTENT_EXPORT
-    TypeConverter<ui::mojom::AttributedStringPtr, NSAttributedString*> {
+    TypeConverter<ui::mojom::AttributedStringPtr, CFAttributedStringRef> {
   static ui::mojom::AttributedStringPtr Convert(
-      const NSAttributedString* ns_attributed_string);
+      const CFAttributedStringRef cf_attributed_string);
 };
 
 }  // namespace mojo
diff --git a/content/common/mac/attributed_string_type_converters.mm b/content/common/mac/attributed_string_type_converters.mm
index 920ba766..8103f185 100644
--- a/content/common/mac/attributed_string_type_converters.mm
+++ b/content/common/mac/attributed_string_type_converters.mm
@@ -7,6 +7,7 @@
 #include <AppKit/AppKit.h>
 
 #include "base/check.h"
+#include "base/mac/foundation_util.h"
 #include "base/mac/scoped_nsobject.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
@@ -33,8 +34,8 @@
 
 }  // namespace
 
-NSAttributedString*
-TypeConverter<NSAttributedString*, ui::mojom::AttributedStringPtr>::Convert(
+CFAttributedStringRef
+TypeConverter<CFAttributedStringRef, ui::mojom::AttributedStringPtr>::Convert(
     const ui::mojom::AttributedStringPtr& mojo_attributed_string) {
   // Create the return value.
   NSString* plain_text =
@@ -47,8 +48,8 @@
   for (const auto& attribute : attributes) {
     // Protect against ranges that are outside the range of the string.
     const gfx::Range& range = attribute.get()->effective_range;
-    if (range.GetMin() > [plain_text length] ||
-        range.GetMax() > [plain_text length]) {
+    if (range.GetMin() > plain_text.length ||
+        range.GetMax() > plain_text.length) {
       continue;
     }
     [decoded_string
@@ -56,20 +57,23 @@
                                              attribute.get()->font_point_size)
                 range:range.ToNSRange()];
   }
-  return decoded_string.autorelease();
+  return base::mac::NSToCFCast(decoded_string.autorelease());
 }
 
 ui::mojom::AttributedStringPtr
-TypeConverter<ui::mojom::AttributedStringPtr, NSAttributedString*>::Convert(
-    const NSAttributedString* ns_attributed_string) {
+TypeConverter<ui::mojom::AttributedStringPtr, CFAttributedStringRef>::Convert(
+    const CFAttributedStringRef cf_attributed_string) {
+  NSAttributedString* ns_attributed_string =
+      base::mac::CFToNSCast(cf_attributed_string);
+
   // Create the return value.
   ui::mojom::AttributedStringPtr attributed_string =
       ui::mojom::AttributedString::New();
   attributed_string->string =
-      base::SysNSStringToUTF16([ns_attributed_string string]);
+      base::SysNSStringToUTF16(ns_attributed_string.string);
 
   // Iterate over all the attributes in the string.
-  NSUInteger length = [ns_attributed_string length];
+  NSUInteger length = ns_attributed_string.length;
   for (NSUInteger i = 0; i < length;) {
     NSRange effective_range;
     NSDictionary* ns_attributes =
@@ -81,8 +85,8 @@
     float font_point_size;
     // Only encode the attributes if the filtered set contains font information.
     if (font) {
-      font_name = base::SysNSStringToUTF16([font fontName]);
-      font_point_size = [font pointSize];
+      font_name = base::SysNSStringToUTF16(font.fontName);
+      font_point_size = font.pointSize;
       if (!font_name.empty()) {
         // Convert the attributes.
         ui::mojom::FontAttributePtr attrs = ui::mojom::FontAttribute::New(
diff --git a/content/common/mac/attributed_string_type_converters_unittest.mm b/content/common/mac/attributed_string_type_converters_unittest.mm
index 17738e0..5ea0982d 100644
--- a/content/common/mac/attributed_string_type_converters_unittest.mm
+++ b/content/common/mac/attributed_string_type_converters_unittest.mm
@@ -8,7 +8,7 @@
 
 #include <memory>
 
-#include "base/mac/scoped_nsobject.h"
+#include "base/mac/foundation_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -16,100 +16,99 @@
 
 class AttributedStringConverterTest : public testing::Test {
  public:
-  NSMutableAttributedString* NewAttrString() {
+  NSMutableAttributedString* AttributedString() {
     NSString* str = @"The quick brown fox jumped over the lazy dog.";
-    return [[NSMutableAttributedString alloc] initWithString:str];
+    return [[[NSMutableAttributedString alloc] initWithString:str] autorelease];
   }
 
-  NSDictionary* FontAttribute(NSString* name, CGFloat size) {
+  NSDictionary* FontAttributeDictionary(NSString* name, CGFloat size) {
     NSFont* font = [NSFont fontWithName:name size:size];
-    return [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName];
+    return @{NSFontAttributeName : font};
   }
 
   NSAttributedString* ConvertAndRestore(NSAttributedString* str) {
     ui::mojom::AttributedStringPtr attributed_str =
-        ui::mojom::AttributedString::From(str);
-    return attributed_str.To<NSAttributedString*>();
+        ui::mojom::AttributedString::From(base::mac::NSToCFCast(str));
+    return base::mac::CFToNSCast(attributed_str.To<CFAttributedStringRef>());
   }
 };
 
 TEST_F(AttributedStringConverterTest, SimpleString) {
-  base::scoped_nsobject<NSMutableAttributedString> attr_str(NewAttrString());
-  [attr_str addAttributes:FontAttribute(@"Helvetica", 12.5)
-                    range:NSMakeRange(0, [attr_str length])];
+  NSMutableAttributedString* attr_str = AttributedString();
+  [attr_str addAttributes:FontAttributeDictionary(@"Helvetica", 12.5)
+                    range:NSMakeRange(0, attr_str.length)];
 
-  NSAttributedString* ns_attributed_string = ConvertAndRestore(attr_str.get());
-  EXPECT_NSEQ(attr_str.get(), ns_attributed_string);
+  NSAttributedString* ns_attributed_string = ConvertAndRestore(attr_str);
+  EXPECT_NSEQ(attr_str, ns_attributed_string);
 }
 
 TEST_F(AttributedStringConverterTest, NoAttributes) {
-  base::scoped_nsobject<NSAttributedString> attr_str(NewAttrString());
-  NSAttributedString* ns_attributed_string = ConvertAndRestore(attr_str.get());
-  EXPECT_NSEQ(attr_str.get(), ns_attributed_string);
+  NSMutableAttributedString* attr_str = AttributedString();
+  NSAttributedString* ns_attributed_string = ConvertAndRestore(attr_str);
+  EXPECT_NSEQ(attr_str, ns_attributed_string);
 }
 
 TEST_F(AttributedStringConverterTest, StripColor) {
-  base::scoped_nsobject<NSMutableAttributedString> attr_str(NewAttrString());
-  const NSUInteger kStringLength = [attr_str length];
+  NSMutableAttributedString* attr_str = AttributedString();
+  const NSUInteger kStringLength = attr_str.length;
   [attr_str addAttribute:NSFontAttributeName
                    value:[NSFont systemFontOfSize:26]
                    range:NSMakeRange(0, kStringLength)];
   [attr_str addAttribute:NSForegroundColorAttributeName
-                   value:[NSColor redColor]
+                   value:NSColor.redColor
                    range:NSMakeRange(0, kStringLength)];
 
-  NSAttributedString* ns_attributed_string = ConvertAndRestore(attr_str.get());
+  NSAttributedString* ns_attributed_string = ConvertAndRestore(attr_str);
 
   NSRange range;
   NSDictionary* attrs = [ns_attributed_string attributesAtIndex:0
                                                  effectiveRange:&range];
   EXPECT_TRUE(NSEqualRanges(NSMakeRange(0, kStringLength), range));
-  EXPECT_NSEQ([NSFont systemFontOfSize:26],
-              [attrs objectForKey:NSFontAttributeName]);
-  EXPECT_FALSE([attrs objectForKey:NSForegroundColorAttributeName]);
+  EXPECT_NSEQ([NSFont systemFontOfSize:26], attrs[NSFontAttributeName]);
+  EXPECT_FALSE(attrs[NSForegroundColorAttributeName]);
 }
 
 TEST_F(AttributedStringConverterTest, MultipleFonts) {
-  base::scoped_nsobject<NSMutableAttributedString> attr_str(NewAttrString());
-  [attr_str setAttributes:FontAttribute(@"Courier", 12)
+  NSMutableAttributedString* attr_str = AttributedString();
+  [attr_str setAttributes:FontAttributeDictionary(@"Courier", 12)
                     range:NSMakeRange(0, 10)];
-  [attr_str addAttributes:FontAttribute(@"Helvetica", 16)
+  [attr_str addAttributes:FontAttributeDictionary(@"Helvetica", 16)
                     range:NSMakeRange(12, 6)];
-  [attr_str addAttributes:FontAttribute(@"Helvetica", 14)
+  [attr_str addAttributes:FontAttributeDictionary(@"Helvetica", 14)
                     range:NSMakeRange(15, 5)];
 
   NSAttributedString* ns_attributed_string = ConvertAndRestore(attr_str);
 
-  EXPECT_NSEQ(attr_str.get(), ns_attributed_string);
+  EXPECT_NSEQ(attr_str, ns_attributed_string);
 }
 
 TEST_F(AttributedStringConverterTest, NoPertinentAttributes) {
-  base::scoped_nsobject<NSMutableAttributedString> attr_str(NewAttrString());
+  NSMutableAttributedString* attr_str = AttributedString();
   [attr_str addAttribute:NSForegroundColorAttributeName
-                   value:[NSColor blueColor]
+                   value:NSColor.blueColor
                    range:NSMakeRange(0, 10)];
   [attr_str addAttribute:NSBackgroundColorAttributeName
-                   value:[NSColor blueColor]
+                   value:NSColor.blueColor
                    range:NSMakeRange(15, 5)];
   [attr_str addAttribute:NSKernAttributeName
-                   value:[NSNumber numberWithFloat:2.6]
+                   value:@(2.6)
                    range:NSMakeRange(11, 3)];
 
-  NSAttributedString* ns_attributed_string = ConvertAndRestore(attr_str.get());
+  NSAttributedString* ns_attributed_string = ConvertAndRestore(attr_str);
 
-  base::scoped_nsobject<NSAttributedString> expected(NewAttrString());
-  EXPECT_NSEQ(expected.get(), ns_attributed_string);
+  NSMutableAttributedString* expected = AttributedString();
+  EXPECT_NSEQ(expected, ns_attributed_string);
 }
 
 TEST_F(AttributedStringConverterTest, NilString) {
   NSAttributedString* ns_attributed_string = ConvertAndRestore(nil);
   EXPECT_TRUE(ns_attributed_string);
-  EXPECT_EQ(0U, [ns_attributed_string length]);
+  EXPECT_EQ(0U, ns_attributed_string.length);
 }
 
 TEST_F(AttributedStringConverterTest, OutOfRange) {
   NSFont* system_font = [NSFont systemFontOfSize:10];
-  std::u16string font_name = base::SysNSStringToUTF16([system_font fontName]);
+  std::u16string font_name = base::SysNSStringToUTF16(system_font.fontName);
   ui::mojom::AttributedStringPtr attributed_string =
       ui::mojom::AttributedString::New();
   attributed_string->string = u"Hello World";
@@ -120,20 +119,21 @@
   attributed_string->attributes.push_back(
       ui::mojom::FontAttribute::New(font_name, 16, gfx::Range(100, 5)));
 
+  CFAttributedStringRef cf_attributed_string =
+      attributed_string.To<CFAttributedStringRef>();
+  EXPECT_TRUE(cf_attributed_string);
   NSAttributedString* ns_attributed_string =
-      attributed_string.To<NSAttributedString*>();
-  EXPECT_TRUE(ns_attributed_string);
+      base::mac::CFToNSCast(cf_attributed_string);
 
   NSRange range;
   NSDictionary* attrs = [ns_attributed_string attributesAtIndex:0
                                                  effectiveRange:&range];
-  EXPECT_NSEQ([NSFont systemFontOfSize:12],
-              [attrs objectForKey:NSFontAttributeName]);
+  EXPECT_NSEQ([NSFont systemFontOfSize:12], attrs[NSFontAttributeName]);
   EXPECT_TRUE(NSEqualRanges(range, NSMakeRange(0, 5)));
 
   attrs = [ns_attributed_string attributesAtIndex:5 effectiveRange:&range];
-  EXPECT_FALSE([attrs objectForKey:NSFontAttributeName]);
-  EXPECT_EQ(0U, [attrs count]);
+  EXPECT_FALSE(attrs[NSFontAttributeName]);
+  EXPECT_EQ(0U, attrs.count);
 }
 
 TEST_F(AttributedStringConverterTest, SystemFontSubstitution) {
@@ -146,14 +146,15 @@
   attributed_string->attributes.push_back(
       ui::mojom::FontAttribute::New(font_name, 12, gfx::Range(0, 5)));
 
+  CFAttributedStringRef cf_attributed_string =
+      attributed_string.To<CFAttributedStringRef>();
+  EXPECT_TRUE(cf_attributed_string);
   NSAttributedString* ns_attributed_string =
-      attributed_string.To<NSAttributedString*>();
-  EXPECT_TRUE(ns_attributed_string);
+      base::mac::CFToNSCast(cf_attributed_string);
 
   NSRange range;
   NSDictionary* attrs = [ns_attributed_string attributesAtIndex:0
                                                  effectiveRange:&range];
-  EXPECT_NSEQ([NSFont systemFontOfSize:12],
-              [attrs objectForKey:NSFontAttributeName]);
+  EXPECT_NSEQ([NSFont systemFontOfSize:12], attrs[NSFontAttributeName]);
   EXPECT_TRUE(NSEqualRanges(range, NSMakeRange(0, 5)));
 }
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn
index a156561..a5a855e 100644
--- a/content/public/android/BUILD.gn
+++ b/content/public/android/BUILD.gn
@@ -230,6 +230,7 @@
     "java/src/org/chromium/content/browser/NfcHost.java",
     "java/src/org/chromium/content/browser/PopupController.java",
     "java/src/org/chromium/content/browser/RenderCoordinatesImpl.java",
+    "java/src/org/chromium/content/browser/RenderFrameMetadataProviderImpl.java",
     "java/src/org/chromium/content/browser/RenderWidgetHostViewImpl.java",
     "java/src/org/chromium/content/browser/ScreenOrientationProviderImpl.java",
     "java/src/org/chromium/content/browser/SpareChildConnection.java",
@@ -449,6 +450,7 @@
     "java/src/org/chromium/content/browser/MediaSessionImpl.java",
     "java/src/org/chromium/content/browser/MessagePayloadJni.java",
     "java/src/org/chromium/content/browser/NfcHost.java",
+    "java/src/org/chromium/content/browser/RenderFrameMetadataProviderImpl.java",
     "java/src/org/chromium/content/browser/RenderWidgetHostViewImpl.java",
     "java/src/org/chromium/content/browser/ScreenOrientationProviderImpl.java",
     "java/src/org/chromium/content/browser/SpeechRecognitionImpl.java",
@@ -648,6 +650,7 @@
     "junit/src/org/chromium/content/browser/BindingManagerTest.java",
     "junit/src/org/chromium/content/browser/ChildProcessConnectionMetricsUnitTest.java",
     "junit/src/org/chromium/content/browser/ChildProcessRankingTest.java",
+    "junit/src/org/chromium/content/browser/ContentUiEventHandlerTest.java",
     "junit/src/org/chromium/content/browser/GestureListenerManagerImplUnitTest.java",
     "junit/src/org/chromium/content/browser/ScreenOrientationProviderImplTest.java",
     "junit/src/org/chromium/content/browser/SpareChildConnectionTest.java",
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentUiEventHandler.java b/content/public/android/java/src/org/chromium/content/browser/ContentUiEventHandler.java
index 7c8a329..b6b59a2a 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentUiEventHandler.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentUiEventHandler.java
@@ -9,6 +9,8 @@
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 
+import androidx.annotation.VisibleForTesting;
+
 import org.chromium.base.UserData;
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
@@ -47,16 +49,21 @@
                 ContentUiEventHandlerJni.get().init(ContentUiEventHandler.this, webContents);
     }
 
+    @VisibleForTesting
+    static ContentUiEventHandler createForTesting(
+            WebContents webContents, long nativeContentUiEventHandler) {
+        ContentUiEventHandler contentUiEventHandler = new ContentUiEventHandler(webContents);
+        contentUiEventHandler.mNativeContentUiEventHandler = nativeContentUiEventHandler;
+        return contentUiEventHandler;
+    }
+
     public void setEventDelegate(InternalAccessDelegate delegate) {
         mEventDelegate = delegate;
     }
 
-    private EventForwarder getEventForwarder() {
-        return mWebContents.getEventForwarder();
-    }
-
+    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
     @CalledByNative
-    private boolean onGenericMotionEvent(MotionEvent event) {
+    protected boolean onGenericMotionEvent(MotionEvent event) {
         if (Gamepad.from(mWebContents).onGenericMotionEvent(event)) return true;
         if (JoystickHandler.fromWebContents(mWebContents).onGenericMotionEvent(event)) return true;
         if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
@@ -69,13 +76,21 @@
                     // TODO(mustaq): Should we include MotionEvent.TOOL_TYPE_STYLUS here?
                     // https://crbug.com/592082
                     if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) {
-                        return onMouseEvent(event);
+                        return onMouseEvent(event, false);
                     }
             }
         }
+        if (isTrackpadEventThatNeedsConversion(event)) {
+            return onMouseEvent(event, true);
+        }
         return mEventDelegate.super_onGenericMotionEvent(event);
     }
 
+    private boolean isTrackpadEventThatNeedsConversion(MotionEvent event) {
+        return mWebContents.getEventForwarder().isTrackpadToMouseEventConversionEnabled()
+                && EventForwarder.isTrackpadClickOrClickAndDragEvent(event);
+    }
+
     private void onMouseWheelEvent(MotionEvent event) {
         assert mNativeContentUiEventHandler != 0;
         ContentUiEventHandlerJni.get().sendMouseWheelEvent(mNativeContentUiEventHandler,
@@ -84,7 +99,7 @@
                 event.getAxisValue(MotionEvent.AXIS_VSCROLL));
     }
 
-    private boolean onMouseEvent(MotionEvent event) {
+    private boolean onMouseEvent(MotionEvent event, boolean shouldConvertToMouseEvent) {
         assert mNativeContentUiEventHandler != 0;
         EventForwarder eventForwarder = mWebContents.getEventForwarder();
         boolean didOffsetEvent = false;
@@ -99,7 +114,8 @@
                 event.getPressure(0), event.getOrientation(0),
                 event.getAxisValue(MotionEvent.AXIS_TILT, 0),
                 EventForwarder.getMouseEventActionButton(event), event.getButtonState(),
-                event.getMetaState(), event.getToolType(0));
+                event.getMetaState(),
+                shouldConvertToMouseEvent ? MotionEvent.TOOL_TYPE_MOUSE : event.getToolType(0));
         if (didOffsetEvent) event.recycle();
         return true;
     }
diff --git a/content/public/android/java/src/org/chromium/content/browser/RenderFrameMetadataProviderImpl.java b/content/public/android/java/src/org/chromium/content/browser/RenderFrameMetadataProviderImpl.java
new file mode 100644
index 0000000..80dbcc58
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/browser/RenderFrameMetadataProviderImpl.java
@@ -0,0 +1,23 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser;
+
+import org.chromium.base.JavaExceptionReporter;
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.JNINamespace;
+
+@JNINamespace("content::android")
+class RenderFrameMetadataProviderImpl {
+    private RenderFrameMetadataProviderImpl() {}
+
+    private static class RenderFrameMetadataProviderRecursiveDeleteException
+            extends RuntimeException {}
+
+    @CalledByNative
+    private static void reportRecursiveDelete() {
+        JavaExceptionReporter.reportException(
+                new RenderFrameMetadataProviderRecursiveDeleteException());
+    }
+}
diff --git a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java
index 56352723..66a4d78 100644
--- a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java
@@ -223,8 +223,8 @@
     }
 
     @CalledByNative
-    @VisibleForTesting
-    static WebContentsImpl create(
+    @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+    public static WebContentsImpl create(
             long nativeWebContentsAndroid, NavigationController navigationController) {
         return new WebContentsImpl(nativeWebContentsAndroid, navigationController);
     }
@@ -1010,6 +1010,35 @@
         return key.cast(data);
     }
 
+    /**
+     * Convenience method to initialize test state. Only use for testing.
+     */
+    @VisibleForTesting
+    public void initializeForTesting() {
+        if (mInternalsHolder == null) {
+            mInternalsHolder = WebContents.createDefaultInternalsHolder();
+        }
+        WebContentsInternalsImpl internals = (WebContentsInternalsImpl) mInternalsHolder.get();
+        if (internals == null) {
+            internals = new WebContentsInternalsImpl();
+            internals.userDataHost = new UserDataHost();
+        }
+        mInternalsHolder.set(internals);
+        mInitialized = true;
+    }
+
+    /**
+     * Convenience method to set user data. Only use for testing.
+     */
+    @VisibleForTesting
+    public <T extends UserData> void setUserDataForTesting(Class<T> key, T userData) {
+        // Be sure to call initializeForTesting() first.
+        assert mInitialized;
+
+        WebContentsInternalsImpl internals = (WebContentsInternalsImpl) mInternalsHolder.get();
+        internals.userDataHost.setUserData(key, userData);
+    }
+
     public <T extends UserData> void removeUserData(Class<T> key) {
         UserDataHost userDataHost = getUserDataHost();
         if (userDataHost == null) return;
@@ -1125,8 +1154,9 @@
                 "Native WebContents already destroyed", mNativeDestroyThrowable);
     }
 
+    @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
     @NativeMethods
-    interface Natives {
+    public interface Natives {
         // This is static to avoid exposing a public destroy method on the native side of this
         // class.
         void destroyWebContents(long webContentsAndroidPtr);
diff --git a/content/public/android/junit/src/org/chromium/content/browser/ContentUiEventHandlerTest.java b/content/public/android/junit/src/org/chromium/content/browser/ContentUiEventHandlerTest.java
new file mode 100644
index 0000000..685058e
--- /dev/null
+++ b/content/public/android/junit/src/org/chromium/content/browser/ContentUiEventHandlerTest.java
@@ -0,0 +1,139 @@
+// 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.content.browser;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.view.InputDevice;
+import android.view.MotionEvent;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.stubbing.Answer;
+import org.robolectric.annotation.Config;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.JniMocker;
+import org.chromium.content.browser.webcontents.WebContentsImpl;
+import org.chromium.content.browser.webcontents.WebContentsImplJni;
+import org.chromium.content_public.browser.NavigationController;
+import org.chromium.ui.MotionEventUtils;
+import org.chromium.ui.base.EventForwarder;
+
+/** Unit tests for {@link ContentUiEventHandler} */
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class ContentUiEventHandlerTest {
+    private static final int NATIVE_WEB_CONTENTS_ANDROID = 1;
+    private static final int NATIVE_CONTENT_UI_EVENT_HANDLER = 2;
+
+    @Mock
+    private NavigationController mNavigationController;
+    @Mock
+    private WebContentsImpl.Natives mWebContentsJniMock;
+    @Mock
+    private ContentUiEventHandler.Natives mContentUiEventHandlerJniMock;
+    @Rule
+    public JniMocker mJniMocker = new JniMocker();
+
+    private ContentUiEventHandler mContentUiEventHandler;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mJniMocker.mock(WebContentsImplJni.TEST_HOOKS, mWebContentsJniMock);
+        mJniMocker.mock(ContentUiEventHandlerJni.TEST_HOOKS, mContentUiEventHandlerJniMock);
+
+        WebContentsImpl webContentsImpl =
+                spy(WebContentsImpl.create(NATIVE_WEB_CONTENTS_ANDROID, mNavigationController));
+        webContentsImpl.initializeForTesting();
+
+        Gamepad gamepad = mock(Gamepad.class);
+        when(gamepad.onGenericMotionEvent(any())).thenReturn(false);
+        webContentsImpl.setUserDataForTesting(Gamepad.class, gamepad);
+
+        JoystickHandler joystickHandler = mock(JoystickHandler.class);
+        when(joystickHandler.onGenericMotionEvent(any())).thenReturn(false);
+        webContentsImpl.setUserDataForTesting(JoystickHandler.class, joystickHandler);
+
+        EventForwarder eventForwarder = mock(EventForwarder.class);
+        when(eventForwarder.isTrackpadToMouseEventConversionEnabled()).thenReturn(true);
+        when(eventForwarder.createOffsetMotionEventIfNeeded(any()))
+                .thenAnswer((Answer<MotionEvent>) invocation -> {
+                    Object[] args = invocation.getArguments();
+                    return (MotionEvent) args[0];
+                });
+        doReturn(eventForwarder).when(webContentsImpl).getEventForwarder();
+
+        mContentUiEventHandler = ContentUiEventHandler.createForTesting(
+                webContentsImpl, NATIVE_CONTENT_UI_EVENT_HANDLER);
+    }
+
+    @Test
+    public void testOnGenericMotionEventSendsTrackpadClicksToNative() {
+        MotionEvent trackpadLeftClickEvent = getTrackpadLeftClickEvent();
+        mContentUiEventHandler.onGenericMotionEvent(getTrackpadLeftClickEvent());
+        verifySendMouseEvent(trackpadLeftClickEvent);
+
+        MotionEvent trackpadRightClickEvent = getTrackRightClickEvent();
+        mContentUiEventHandler.onGenericMotionEvent(getTrackRightClickEvent());
+        verifySendMouseEvent(trackpadRightClickEvent);
+    }
+
+    private void verifySendMouseEvent(MotionEvent event) {
+        verify(mContentUiEventHandlerJniMock)
+                .sendMouseEvent(NATIVE_CONTENT_UI_EVENT_HANDLER, mContentUiEventHandler,
+                        MotionEventUtils.getEventTimeNano(event), event.getActionMasked(),
+                        event.getX(), event.getY(), event.getPointerId(0), event.getPressure(0),
+                        event.getOrientation(0), event.getAxisValue(MotionEvent.AXIS_TILT, 0),
+                        EventForwarder.getMouseEventActionButton(event), event.getButtonState(),
+                        event.getMetaState(), MotionEvent.TOOL_TYPE_MOUSE);
+    }
+
+    private static MotionEvent getTrackpadLeftClickEvent() {
+        return getTrackpadEvent(MotionEvent.ACTION_BUTTON_PRESS, MotionEvent.BUTTON_PRIMARY);
+    }
+
+    private static MotionEvent getTrackRightClickEvent() {
+        return getTrackpadEvent(MotionEvent.ACTION_BUTTON_PRESS, MotionEvent.BUTTON_SECONDARY);
+    }
+
+    private static MotionEvent getTrackpadEvent(int action, int buttonState) {
+        return MotionEvent.obtain(0, 1, action, 1, getToolTypeFingerProperties(),
+                getPointerCoords(), 0, buttonState, 0, 0, 0, 0, getTrackpadSource(), 0);
+    }
+
+    private static MotionEvent.PointerProperties[] getToolTypeFingerProperties() {
+        MotionEvent.PointerProperties[] pointerPropertiesArray =
+                new MotionEvent.PointerProperties[1];
+        MotionEvent.PointerProperties trackpadProperties = new MotionEvent.PointerProperties();
+        trackpadProperties.id = 7;
+        trackpadProperties.toolType = MotionEvent.TOOL_TYPE_FINGER;
+        pointerPropertiesArray[0] = trackpadProperties;
+        return pointerPropertiesArray;
+    }
+
+    private static MotionEvent.PointerCoords[] getPointerCoords() {
+        MotionEvent.PointerCoords[] pointerCoordsArray = new MotionEvent.PointerCoords[1];
+        MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords();
+        coords.x = 14;
+        coords.y = 21;
+        pointerCoordsArray[0] = coords;
+        return pointerCoordsArray;
+    }
+
+    private static int getTrackpadSource() {
+        return InputDevice.SOURCE_MOUSE;
+    }
+}
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn
index 3e51341..6c75fdb 100644
--- a/content/public/browser/BUILD.gn
+++ b/content/public/browser/BUILD.gn
@@ -635,7 +635,6 @@
     sources += [
       "chromeos/multi_capture_service.cc",
       "chromeos/multi_capture_service.h",
-      "firewall_hole_proxy.h",
       "lock_screen_storage.h",
       "smart_card_delegate.h",
     ]
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index bf19525f..8182fa1 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -76,10 +76,6 @@
 #include "content/public/browser/tts_environment_android.h"
 #endif
 
-#if BUILDFLAG(IS_CHROMEOS)
-#include "content/public/browser/firewall_hole_proxy.h"
-#endif
-
 namespace content {
 
 std::unique_ptr<BrowserMainParts> ContentBrowserClient::CreateBrowserMainParts(
diff --git a/content/public/browser/firewall_hole_proxy.h b/content/public/browser/firewall_hole_proxy.h
deleted file mode 100644
index 25b3bd0..0000000
--- a/content/public/browser/firewall_hole_proxy.h
+++ /dev/null
@@ -1,44 +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_PUBLIC_BROWSER_FIREWALL_HOLE_PROXY_H_
-#define CONTENT_PUBLIC_BROWSER_FIREWALL_HOLE_PROXY_H_
-
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "base/functional/callback_forward.h"
-#include "content/common/content_export.h"
-
-namespace content {
-
-// FirewallHoleProxy represents a hole in the ChromeOS system firewall.
-// When this class gets destroyed, it's supposed the close the corresponding
-// firewall hole.
-class CONTENT_EXPORT FirewallHoleProxy {
- public:
-  using OpenCallback =
-      base::OnceCallback<void(std::unique_ptr<FirewallHoleProxy>)>;
-
-  virtual ~FirewallHoleProxy() = default;
-};
-
-// Opens a TCP port on the system firewall for the given |interface|
-// (or all interfaces if |interface| is ""). On success invokes the callback
-// with a valid FirewallHoleProxy; on failure supplies nullptr.
-CONTENT_EXPORT void OpenTCPFirewallHole(const std::string& interface,
-                         uint16_t port,
-                         FirewallHoleProxy::OpenCallback callback);
-
-// Opens a UDP port on the system firewall for the given |interface|
-// (or all interfaces if |interface| is ""). On success invokes the callback
-// with a valid FirewallHoleProxy; on failure supplies nullptr.
-CONTENT_EXPORT void OpenUDPFirewallHole(const std::string& interface,
-                         uint16_t port,
-                         FirewallHoleProxy::OpenCallback callback);
-
-}  // namespace content
-
-#endif  // CONTENT_PUBLIC_BROWSER_FIREWALL_HOLE_PROXY_H_
diff --git a/content/public/browser/web_ui.h b/content/public/browser/web_ui.h
index 95c65d15..e4492b87 100644
--- a/content/public/browser/web_ui.h
+++ b/content/public/browser/web_ui.h
@@ -21,6 +21,7 @@
 
 namespace content {
 
+class RenderFrameHost;
 class WebContents;
 class WebUIController;
 class WebUIMessageHandler;
@@ -50,6 +51,14 @@
   virtual WebUIController* GetController() = 0;
   virtual void SetController(std::unique_ptr<WebUIController> controller) = 0;
 
+  // This might return nullptr
+  //  1. During construction, until the WebUI is associated with
+  //     a RenderFrameHost.
+  //  2. During destruction, if the WebUI's destruction causes the
+  //     RenderFrameHost to be destroyed (crbug.com/1308391).
+  //  3. In unittests where the WebUI is mocked, notably by TestWebUI.
+  virtual RenderFrameHost* GetRenderFrameHost() = 0;
+
   // Returns the device scale factor of the monitor that the renderer is on.
   // Whenever possible, WebUI should push resources with this scale factor to
   // Javascript.
diff --git a/content/public/browser/web_ui_controller.cc b/content/public/browser/web_ui_controller.cc
index d23f987f..0e990df 100644
--- a/content/public/browser/web_ui_controller.cc
+++ b/content/public/browser/web_ui_controller.cc
@@ -5,6 +5,7 @@
 #include "content/public/browser/web_ui_controller.h"
 
 #include "content/browser/renderer_host/render_frame_host_impl.h"
+#include "content/browser/webui/web_ui_managed_interface.h"
 #include "content/public/browser/web_ui_browser_interface_broker_registry.h"
 
 namespace content {
@@ -21,7 +22,9 @@
 
 WebUIController::WebUIController(WebUI* web_ui) : web_ui_(web_ui) {}
 
-WebUIController::~WebUIController() = default;
+WebUIController::~WebUIController() {
+  RemoveWebUIManagedInterfaces(this);
+}
 
 bool WebUIController::OverrideHandleWebUIMessage(
     const GURL& source_url,
diff --git a/content/public/test/back_forward_cache_util.cc b/content/public/test/back_forward_cache_util.cc
index 6a0c862f..0194ad3 100644
--- a/content/public/test/back_forward_cache_util.cc
+++ b/content/public/test/back_forward_cache_util.cc
@@ -211,4 +211,17 @@
   return final_features;
 }
 
+void InitBackForwardCacheFeature(base::test::ScopedFeatureList* feature_list,
+                                 bool enable_back_forward_cache) {
+  if (enable_back_forward_cache) {
+    feature_list->InitWithFeaturesAndParameters(
+        GetBasicBackForwardCacheFeatureForTesting(
+            {{kBackForwardCacheNoTimeEviction, {}},
+             {features::kBackForwardCacheMemoryControls, {}}}),
+        {});
+  } else {
+    feature_list->InitAndDisableFeature(features::kBackForwardCache);
+  }
+}
+
 }  // namespace content
diff --git a/content/public/test/back_forward_cache_util.h b/content/public/test/back_forward_cache_util.h
index fe91afe..4b65bb2 100644
--- a/content/public/test/back_forward_cache_util.h
+++ b/content/public/test/back_forward_cache_util.h
@@ -129,6 +129,10 @@
 GetDefaultDisabledBackForwardCacheFeaturesForTesting(
     const std::vector<base::test::FeatureRef>& additional_features);
 
+// Initializes BFCache to `enable_back_forward_cache` for `feature_list`.
+void InitBackForwardCacheFeature(base::test::ScopedFeatureList* feature_list,
+                                 bool enable_back_forward_cache);
+
 }  // namespace content
 
 #endif  // CONTENT_PUBLIC_TEST_BACK_FORWARD_CACHE_UTIL_H_
diff --git a/content/public/test/content_browser_test_utils_mac.mm b/content/public/test/content_browser_test_utils_mac.mm
index 181d41f..9b5a267f 100644
--- a/content/public/test/content_browser_test_utils_mac.mm
+++ b/content/public/test/content_browser_test_utils_mac.mm
@@ -142,8 +142,8 @@
               const gfx::Point& baseline_point) {
             std::string string =
                 attributed_string
-                    ? base::SysNSStringToUTF8(
-                          [attributed_string.To<NSAttributedString*>() string])
+                    ? base::SysCFStringRefToUTF8(CFAttributedStringGetString(
+                          attributed_string.To<CFAttributedStringRef>()))
                     : std::string();
             std::move(callback).Run(string, baseline_point);
           }),
@@ -165,8 +165,8 @@
               const gfx::Point& baseline_point) {
             std::string string =
                 attributed_string
-                    ? base::SysNSStringToUTF8(
-                          [attributed_string.To<NSAttributedString*>() string])
+                    ? base::SysCFStringRefToUTF8(CFAttributedStringGetString(
+                          attributed_string.To<CFAttributedStringRef>()))
                     : std::string();
             std::move(callback).Run(string, baseline_point);
           }),
diff --git a/content/public/test/test_web_ui.cc b/content/public/test/test_web_ui.cc
index fe6a71a..3cb32eb 100644
--- a/content/public/test/test_web_ui.cc
+++ b/content/public/test/test_web_ui.cc
@@ -48,6 +48,10 @@
   return controller_.get();
 }
 
+RenderFrameHost* TestWebUI::GetRenderFrameHost() {
+  return nullptr;
+}
+
 void TestWebUI::SetController(std::unique_ptr<WebUIController> controller) {
   controller_ = std::move(controller);
 }
diff --git a/content/public/test/test_web_ui.h b/content/public/test/test_web_ui.h
index 83a1214..a62df0f 100644
--- a/content/public/test/test_web_ui.h
+++ b/content/public/test/test_web_ui.h
@@ -39,6 +39,7 @@
   // WebUI overrides.
   WebContents* GetWebContents() override;
   WebUIController* GetController() override;
+  RenderFrameHost* GetRenderFrameHost() override;
   void SetController(std::unique_ptr<WebUIController> controller) override;
   float GetDeviceScaleFactor() override;
   const std::u16string& GetOverriddenTitle() override;
diff --git a/content/renderer/render_thread_impl_browsertest.cc b/content/renderer/render_thread_impl_browsertest.cc
index 0be71f2..cd449c72 100644
--- a/content/renderer/render_thread_impl_browsertest.cc
+++ b/content/renderer/render_thread_impl_browsertest.cc
@@ -23,6 +23,7 @@
 #include "base/task/single_thread_task_runner.h"
 #include "base/task/thread_pool/thread_pool_instance.h"
 #include "base/test/test_switches.h"
+#include "cc/base/switches.h"
 #include "content/app/mojo/mojo_init.h"
 #include "content/common/in_process_child_thread_params.h"
 #include "content/common/pseudonymization_salt.h"
@@ -48,7 +49,6 @@
 #include "gpu/config/gpu_switches.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/common/switches.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
 #include "third_party/blink/public/platform/scheduler/test/web_mock_thread_scheduler.h"
@@ -179,7 +179,7 @@
 
     cmd->AppendSwitchASCII(switches::kLang, "en-US");
 
-    cmd->AppendSwitchASCII(blink::switches::kNumRasterThreads, "1");
+    cmd->AppendSwitchASCII(cc::switches::kNumRasterThreads, "1");
 
     // To avoid creating a GPU channel to query if
     // accelerated_video_decode is blocklisted on older Android system
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index bb4395ae..309475a 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -1048,6 +1048,7 @@
 mojom("web_ui_test_mojo_bindings") {
   testonly = true
   sources = [
+    "data/web_ui_managed_interface_test.test-mojom",
     "data/web_ui_test.test-mojom",
     "data/web_ui_test_types.test-mojom",
   ]
@@ -1445,6 +1446,7 @@
     "../browser/renderer_host/input/wheel_scroll_latching_browsertest.cc",
     "../browser/renderer_host/isolated_web_app_throttle_browsertest.cc",
     "../browser/renderer_host/media/video_capture_browsertest.cc",
+    "../browser/renderer_host/navigation_controller_history_intervention_browsertest.cc",
     "../browser/renderer_host/navigation_controller_impl_browsertest.cc",
     "../browser/renderer_host/navigation_handle_user_data_browsertest.cc",
     "../browser/renderer_host/navigation_policy_container_builder_browsertest.cc",
@@ -1549,6 +1551,7 @@
     "../browser/webrtc/webrtc_webcam_browsertest.cc",
     "../browser/webrtc/webrtc_webcam_browsertest.h",
     "../browser/webui/web_ui_browsertest.cc",
+    "../browser/webui/web_ui_managed_interface_browsertest.cc",
     "../browser/webui/web_ui_mojo_browsertest.cc",
     "../browser/webui/web_ui_navigation_browsertest.cc",
     "../browser/webui/web_ui_security_browsertest.cc",
diff --git a/content/test/content_unittests_bundle_data.filelist b/content/test/content_unittests_bundle_data.filelist
index 32c8395c..b2da4dde 100644
--- a/content/test/content_unittests_bundle_data.filelist
+++ b/content/test/content_unittests_bundle_data.filelist
@@ -1809,6 +1809,9 @@
 data/web_bundle/web_bundle_browsertest_b2.wbn
 data/web_bundle/web_bundle_browsertest_b2.wbn.mock-http-headers
 data/web_ui_dedicated_worker.js
+data/web_ui_managed_interface_test.html
+data/web_ui_managed_interface_test.js
+data/web_ui_managed_interface_test.test-mojom
 data/web_ui_mojo_native.html
 data/web_ui_mojo_native.js
 data/web_ui_mojo_test.html
diff --git a/content/test/data/web_ui_managed_interface_test.html b/content/test/data/web_ui_managed_interface_test.html
new file mode 100644
index 0000000..b35460c
--- /dev/null
+++ b/content/test/data/web_ui_managed_interface_test.html
@@ -0,0 +1,10 @@
+<!--
+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.
+-->
+
+<html>
+<title>Foo</title>
+<script src="/web_ui_managed_interface_test.js" type="module"></script>
+</html>
diff --git a/content/test/data/web_ui_managed_interface_test.js b/content/test/data/web_ui_managed_interface_test.js
new file mode 100644
index 0000000..ce7679b
--- /dev/null
+++ b/content/test/data/web_ui_managed_interface_test.js
@@ -0,0 +1,9 @@
+// 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 {BarCallbackRouter, BazCallbackRouter, FooRemote, TestWebUIJsBridge} from '/web_ui_managed_interface_test.test-mojom-webui.js';
+
+Object.assign(
+    window,
+    {BarCallbackRouter, BazCallbackRouter, FooRemote, TestWebUIJsBridge});
diff --git a/content/test/data/web_ui_managed_interface_test.test-mojom b/content/test/data/web_ui_managed_interface_test.test-mojom
new file mode 100644
index 0000000..781b773
--- /dev/null
+++ b/content/test/data/web_ui_managed_interface_test.test-mojom
@@ -0,0 +1,32 @@
+// 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.
+
+module content.mojom;
+
+interface Foo {
+  GetFoo() => (string value);
+};
+
+interface Bar {
+  GetBar() => (string value);
+};
+
+interface Baz {
+  GetBaz() => (string value);
+};
+
+// A bridge (aka Factory) interface that is used for binding other
+// interfaces.
+interface TestWebUIJsBridge {
+  // The WebUI calls this method to bind a Foo remote.
+  BindFoo(pending_receiver<Foo> foo);
+
+  // The WebUI calls this method to bind a Foo remote and provide the
+  // browser with a Bar remote.
+  BindFooBar(pending_receiver<Foo> foo,
+             pending_remote<Bar> bar);
+
+  // The WebUI calls this method to provide the browser with a Baz remote.
+  BindBaz(pending_remote<Baz> baz);
+};
diff --git a/content/test/gpu/gpu_tests/test_expectations/cast_streaming_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/cast_streaming_expectations.txt
index f0a167b..9fe1b91 100644
--- a/content/test/gpu/gpu_tests/test_expectations/cast_streaming_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/cast_streaming_expectations.txt
@@ -20,7 +20,8 @@
 # tags: [ android-chromium android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell ]
+#         fuchsia-chrome web-engine-shell
+#         lacros-chrome cros-chrome ]
 # GPU
 # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340
 #         apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/gpu/gpu_tests/test_expectations/context_lost_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/context_lost_expectations.txt
index ba87993..92d61bd 100644
--- a/content/test/gpu/gpu_tests/test_expectations/context_lost_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/context_lost_expectations.txt
@@ -20,7 +20,8 @@
 # tags: [ android-chromium android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell ]
+#         fuchsia-chrome web-engine-shell
+#         lacros-chrome cros-chrome ]
 # GPU
 # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340
 #         apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/gpu/gpu_tests/test_expectations/gpu_process_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/gpu_process_expectations.txt
index 7fb9c94d..0216d36 100644
--- a/content/test/gpu/gpu_tests/test_expectations/gpu_process_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/gpu_process_expectations.txt
@@ -20,7 +20,8 @@
 # tags: [ android-chromium android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell ]
+#         fuchsia-chrome web-engine-shell
+#         lacros-chrome cros-chrome ]
 # GPU
 # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340
 #         apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/gpu/gpu_tests/test_expectations/hardware_accelerated_feature_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/hardware_accelerated_feature_expectations.txt
index 36dee58..3e36540d 100644
--- a/content/test/gpu/gpu_tests/test_expectations/hardware_accelerated_feature_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/hardware_accelerated_feature_expectations.txt
@@ -20,7 +20,8 @@
 # tags: [ android-chromium android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell ]
+#         fuchsia-chrome web-engine-shell
+#         lacros-chrome cros-chrome ]
 # GPU
 # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340
 #         apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/gpu/gpu_tests/test_expectations/info_collection_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/info_collection_expectations.txt
index 20db553..d0c0cf56 100644
--- a/content/test/gpu/gpu_tests/test_expectations/info_collection_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/info_collection_expectations.txt
@@ -20,7 +20,8 @@
 # tags: [ android-chromium android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell ]
+#         fuchsia-chrome web-engine-shell
+#         lacros-chrome cros-chrome ]
 # GPU
 # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340
 #         apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/gpu/gpu_tests/test_expectations/maps_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/maps_expectations.txt
index d7d4730b..03171ba 100644
--- a/content/test/gpu/gpu_tests/test_expectations/maps_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/maps_expectations.txt
@@ -20,7 +20,8 @@
 # tags: [ android-chromium android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell ]
+#         fuchsia-chrome web-engine-shell
+#         lacros-chrome cros-chrome ]
 # GPU
 # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340
 #         apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/gpu/gpu_tests/test_expectations/mediapipe_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/mediapipe_expectations.txt
index cf9fc31..1b88e07 100644
--- a/content/test/gpu/gpu_tests/test_expectations/mediapipe_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/mediapipe_expectations.txt
@@ -20,7 +20,8 @@
 # tags: [ android-chromium android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell ]
+#         fuchsia-chrome web-engine-shell
+#         lacros-chrome cros-chrome ]
 # GPU
 # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340
 #         apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
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 34539494..36e5b73 100644
--- a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
@@ -20,7 +20,8 @@
 # tags: [ android-chromium android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell ]
+#         fuchsia-chrome web-engine-shell
+#         lacros-chrome cros-chrome ]
 # GPU
 # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340
 #         apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
@@ -264,8 +265,8 @@
 crbug.com/1201009 [ fuchsia ] Pixel_VideoStreamFromWebGLCanvas_TwoCopy_Accelerated [ Skip ]
 
 # 5 minute timeout on ChromeOS FYI Release (both amd64-generic and kevin)
-crbug.com/1353952 [ chromeos chromeos-board-amd64-generic ] Pixel_WebGLContextRestored [ Skip ]
-crbug.com/1353952 [ chromeos chromeos-board-kevin ] Pixel_WebGLContextRestored [ Skip ]
+crbug.com/1353952 [ chromeos cros-chrome chromeos-board-amd64-generic ] Pixel_WebGLContextRestored [ Skip ]
+crbug.com/1353952 [ chromeos cros-chrome chromeos-board-kevin ] Pixel_WebGLContextRestored [ Skip ]
 
 ###################
 # Failures/Flakes #
@@ -392,6 +393,12 @@
 crbug.com/1418987 [ linux amd-0x7340 angle-vulkan ] Pixel_OffscreenCanvasAccelerated2D [ RetryOnFailure ]
 crbug.com/1418987 [ linux amd-0x7340 angle-vulkan ] Pixel_OffscreenCanvasWebGLDefaultWorker [ RetryOnFailure ]
 
+# Lacros consistent failures on CrOS devices, skip to save some time
+crbug.com/1392806 [ chromeos lacros-chrome ] Pixel_CanvasDisplaySRGBAccelerated2D [ Skip ]
+crbug.com/1392806 [ chromeos lacros-chrome ] Pixel_Video_Context_Loss_MP4 [ Skip ]
+crbug.com/1392806 [ chromeos lacros-chrome ] Pixel_Video_Context_Loss_VP9 [ Skip ]
+crbug.com/1392806 [ chromeos lacros-chrome ] Pixel_WebGLContextRestored [ Skip ]
+crbug.com/1392806 [ chromeos lacros-chrome ] Pixel_WebGLPreservedAfterTabSwitch [ Skip ]
 
 
 #######################################################################
diff --git a/content/test/gpu/gpu_tests/test_expectations/power_measurement_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/power_measurement_expectations.txt
index 36dee58..3e36540d 100644
--- a/content/test/gpu/gpu_tests/test_expectations/power_measurement_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/power_measurement_expectations.txt
@@ -20,7 +20,8 @@
 # tags: [ android-chromium android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell ]
+#         fuchsia-chrome web-engine-shell
+#         lacros-chrome cros-chrome ]
 # GPU
 # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340
 #         apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/gpu/gpu_tests/test_expectations/screenshot_sync_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/screenshot_sync_expectations.txt
index 9b9d3b4..bfb21028 100644
--- a/content/test/gpu/gpu_tests/test_expectations/screenshot_sync_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/screenshot_sync_expectations.txt
@@ -20,7 +20,8 @@
 # tags: [ android-chromium android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell ]
+#         fuchsia-chrome web-engine-shell
+#         lacros-chrome cros-chrome ]
 # GPU
 # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340
 #         apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt
index 3ea66ba8..2246b8e 100644
--- a/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt
@@ -20,7 +20,8 @@
 # tags: [ android-chromium android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell ]
+#         fuchsia-chrome web-engine-shell
+#         lacros-chrome cros-chrome ]
 # GPU
 # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340
 #         apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
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 13be7d8..df13df2 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt
@@ -20,7 +20,8 @@
 # tags: [ android-chromium android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell ]
+#         fuchsia-chrome web-engine-shell
+#         lacros-chrome cros-chrome ]
 # GPU
 # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340
 #         apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
index 87fd7c2..7111f523 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -20,7 +20,8 @@
 # tags: [ android-chromium android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell ]
+#         fuchsia-chrome web-engine-shell
+#         lacros-chrome cros-chrome ]
 # GPU
 # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340
 #         apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
index 8969c970..0db914f 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -20,7 +20,8 @@
 # tags: [ android-chromium android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell ]
+#         fuchsia-chrome web-engine-shell
+#         lacros-chrome cros-chrome ]
 # GPU
 # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340
 #         apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/gpu/validate_tag_consistency.py b/content/test/gpu/validate_tag_consistency.py
index 72417817..f651612 100755
--- a/content/test/gpu/validate_tag_consistency.py
+++ b/content/test/gpu/validate_tag_consistency.py
@@ -33,7 +33,8 @@
 # tags: [ android-chromium android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell ]
+#         fuchsia-chrome web-engine-shell
+#         lacros-chrome cros-chrome ]
 # GPU
 # tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340
 #         apple apple-apple-m1 apple-angle-metal-renderer:-apple-m1
diff --git a/content/test/web_ui_mojo_test_resources.grd b/content/test/web_ui_mojo_test_resources.grd
index 1efffd8..cfd054c 100644
--- a/content/test/web_ui_mojo_test_resources.grd
+++ b/content/test/web_ui_mojo_test_resources.grd
@@ -14,6 +14,9 @@
   <translations />
   <release seq="1">
     <includes>
+      <include name="IDR_WEB_UI_MANAGED_INTERFACE_TEST_HTML" file="data/web_ui_managed_interface_test.html" type="BINDATA" resource_path="web_ui_managed_interface_test.html" />
+      <include name="IDR_WEB_UI_MANAGED_INTERFACE_TEST_JS" file="data/web_ui_managed_interface_test.js" type="BINDATA" resource_path="web_ui_managed_interface_test.js" />
+      <include name="IDR_WEB_UI_MANAGED_INTERFACE_TEST_TEST_MOJOM_WEBUI_JS" file="${root_gen_dir}/mojom-webui/content/test/data/web_ui_managed_interface_test.test-mojom-webui.js" use_base_dir="false" type="BINDATA" resource_path="web_ui_managed_interface_test.test-mojom-webui.js" />
       <include name="IDR_WEB_UI_MOJO_HTML" file="data/web_ui_mojo_test.html" type="BINDATA" />
       <include name="IDR_WEB_UI_MOJO_JS" file="data/web_ui_mojo_test.js" type="BINDATA" resource_path="web_ui_mojo_test.js" />
       <include name="IDR_WEB_UI_MOJO_TS_HTML" file="data/web_ui_mojo_ts_test.html" type="BINDATA" />
diff --git a/docs/security/faq.md b/docs/security/faq.md
index 37fc27f..79f87620 100644
--- a/docs/security/faq.md
+++ b/docs/security/faq.md
@@ -371,12 +371,14 @@
 bar or the DevTools console.
 
 <a name="TOC-Does-executing-JavaScript-from-a-bookmark-mean-there-s-an-XSS-vulnerability-"></a>
-### Does executing JavaScript from a bookmark mean there's an XSS vulnerability?
+### Does executing JavaScript from a bookmark or the Home button mean there's an XSS vulnerability?
 
 No. Chromium allows users to create bookmarks to JavaScript URLs that will run
 on the currently-loaded page when the user clicks the bookmark; these are called
 [bookmarklets](https://en.wikipedia.org/wiki/Bookmarklet).
 
+Similarly, the Home button may be configured to invoke a JavaScript URL when clicked.
+
 <a name="TOC-Does-executing-JavaScript-in-a-PDF-file-mean-there-s-an-XSS-vulnerability-"></a>
 ### Does executing JavaScript in a PDF file mean there's an XSS vulnerability?
 
diff --git a/docs/security/security-labels.md b/docs/security/security-labels.md
index b7bfca16..19e00009 100644
--- a/docs/security/security-labels.md
+++ b/docs/security/security-labels.md
@@ -110,7 +110,7 @@
 **Security_Impact**, **OS**, **Pri**, **M**, **Component**, and an
 **owner** set.
 
-### When to use Security_Impact-None {#TOC-Security_Impact-None}
+### When to use Security_Impact-None {#TOC-Security-Impact-None}
 
 **Security_Impact-None** says that the bug can't affect any users running the
 default configuration of Chrome. It's most commonly used for cases where
diff --git a/gpu/command_buffer/service/dxgi_shared_handle_manager.cc b/gpu/command_buffer/service/dxgi_shared_handle_manager.cc
index 8878ece..31b05dd 100644
--- a/gpu/command_buffer/service/dxgi_shared_handle_manager.cc
+++ b/gpu/command_buffer/service/dxgi_shared_handle_manager.cc
@@ -8,6 +8,7 @@
 #include <windows.h>
 
 #include "base/atomic_ref_count.h"
+#include "base/debug/dump_without_crashing.h"
 #include "base/logging.h"
 #include "gpu/command_buffer/common/constants.h"
 #include "ui/gl/gl_angle_util_win.h"
@@ -94,6 +95,8 @@
 
   if (acquired_for_d3d12_) {
     DLOG(ERROR) << "Recursive BeginAccess not supported";
+    // TODO(crbug.com/1430941): Remove after fixing overlay access crash.
+    base::debug::DumpWithoutCrashing();
     return false;
   }
   if (acquired_for_d3d11_count_ > 0) {
@@ -104,6 +107,8 @@
       dxgi_keyed_mutex_->AcquireSync(kDXGIKeyedMutexAcquireKey, INFINITE);
   if (FAILED(hr)) {
     DLOG(ERROR) << "Unable to acquire the keyed mutex " << std::hex << hr;
+    // TODO(crbug.com/1430941): Remove after fixing overlay access crash.
+    base::debug::DumpWithoutCrashing();
     return false;
   }
   acquired_for_d3d11_count_++;
diff --git a/gpu/command_buffer/service/shared_context_state.cc b/gpu/command_buffer/service/shared_context_state.cc
index 60fb514..9960748 100644
--- a/gpu/command_buffer/service/shared_context_state.cc
+++ b/gpu/command_buffer/service/shared_context_state.cc
@@ -370,12 +370,13 @@
 bool SharedContextState::InitializeGraphite(
     const GpuPreferences& gpu_preferences) {
 #if BUILDFLAG(ENABLE_SKIA_GRAPHITE)
-  skgpu::graphite::ContextOptions options = GetDefaultGraphiteContextOptions();
+  skgpu::graphite::ContextOptions context_options =
+      GetDefaultGraphiteContextOptions();
 
   if (gr_context_type_ == GrContextType::kGraphiteDawn) {
 #if BUILDFLAG(SKIA_USE_DAWN)
     if (dawn_context_provider_ &&
-        dawn_context_provider_->InitializeGraphiteContext(options)) {
+        dawn_context_provider_->InitializeGraphiteContext(context_options)) {
       graphite_context_ = dawn_context_provider_->GetGraphiteContext();
     } else {
       DLOG(ERROR) << "Failed to create Graphite Context for Dawn";
@@ -385,7 +386,7 @@
     CHECK_EQ(gr_context_type_, GrContextType::kGraphiteMetal);
 #if BUILDFLAG(SKIA_USE_METAL)
     if (metal_context_provider_ &&
-        metal_context_provider_->InitializeGraphiteContext(options)) {
+        metal_context_provider_->InitializeGraphiteContext(context_options)) {
       graphite_context_ = metal_context_provider_->GetGraphiteContext();
     } else {
       DLOG(ERROR) << "Failed to create Graphite Context for Metal";
@@ -397,7 +398,8 @@
     LOG(ERROR) << "Skia Graphite disabled: Graphite Context creation failed.";
     return false;
   }
-  // TODO(crbug.com/1429361): Create graphite recorders here.
+  gpu_main_graphite_recorder_ = graphite_context_->makeRecorder();
+  viz_compositor_graphite_recorder_ = graphite_context_->makeRecorder();
   transfer_cache_ = std::make_unique<ServiceTransferCache>(gpu_preferences);
   return true;
 #else   // BUILDFLAG(ENABLE_SKIA_GRAPHITE)
diff --git a/gpu/command_buffer/service/shared_context_state.h b/gpu/command_buffer/service/shared_context_state.h
index fab84ad..c07796e 100644
--- a/gpu/command_buffer/service/shared_context_state.h
+++ b/gpu/command_buffer/service/shared_context_state.h
@@ -29,6 +29,7 @@
 #include "gpu/ipc/common/command_buffer_id.h"
 #include "gpu/ipc/common/gpu_peak_memory.h"
 #include "gpu/vulkan/buildflags.h"
+#include "skia/buildflags.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkSurface.h"
 #include "third_party/skia/include/gpu/GrDirectContext.h"
@@ -49,6 +50,7 @@
 
 namespace skgpu::graphite {
 class Context;
+class Recorder;
 }  // namespace skgpu::graphite
 
 namespace gpu {
@@ -139,10 +141,30 @@
     return dawn_context_provider_;
   }
   gl::ProgressReporter* progress_reporter() const { return progress_reporter_; }
+  // Ganesh/Graphite contexts may only be used on the GPU main thread.
   GrDirectContext* gr_context() { return gr_context_; }
+#if BUILDFLAG(ENABLE_SKIA_GRAPHITE)
   skgpu::graphite::Context* graphite_context() const {
     return graphite_context_;
   }
+  // Graphite recorder for GPU main thread, used by RasterDecoder,
+  // SkiaOutputSurfaceImplOnGpu, etc.
+  skgpu::graphite::Recorder* gpu_main_graphite_recorder() const {
+    return gpu_main_graphite_recorder_.get();
+  }
+  // Graphite recorder for Viz compositor thread, used by SkiaOutputSurfaceImpl.
+  skgpu::graphite::Recorder* viz_compositor_graphite_recorder() const {
+    return viz_compositor_graphite_recorder_.get();
+  }
+#else
+  skgpu::graphite::Context* graphite_context() const { return nullptr; }
+  skgpu::graphite::Recorder* gpu_main_graphite_recorder() const {
+    return nullptr;
+  }
+  skgpu::graphite::Recorder* viz_compositor_graphite_recorder() const {
+    return nullptr;
+  }
+#endif
   GrContextType gr_context_type() const { return gr_context_type_; }
   // Handles Skia-reported shader compilation errors.
   void compileError(const char* shader, const char* errors) override;
@@ -330,7 +352,11 @@
   const raw_ptr<viz::DawnContextProvider> dawn_context_provider_ = nullptr;
   bool created_on_compositor_gpu_thread_ = false;
   raw_ptr<GrDirectContext> gr_context_ = nullptr;
+#if BUILDFLAG(ENABLE_SKIA_GRAPHITE)
   raw_ptr<skgpu::graphite::Context> graphite_context_ = nullptr;
+  std::unique_ptr<skgpu::graphite::Recorder> gpu_main_graphite_recorder_;
+  std::unique_ptr<skgpu::graphite::Recorder> viz_compositor_graphite_recorder_;
+#endif
 
   scoped_refptr<gl::GLShareGroup> share_group_;
   scoped_refptr<gl::GLContext> context_;
diff --git a/gpu/command_buffer/service/shared_image/d3d_image_backing.cc b/gpu/command_buffer/service/shared_image/d3d_image_backing.cc
index f3d6bbc9..1c49881 100644
--- a/gpu/command_buffer/service/shared_image/d3d_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/d3d_image_backing.cc
@@ -6,6 +6,7 @@
 
 #include <d3d11_3.h>
 
+#include "base/debug/dump_without_crashing.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
 #include "base/memory/ptr_util.h"
@@ -965,8 +966,11 @@
 #endif
 
 bool D3DImageBacking::BeginAccessD3D11(bool write_access) {
-  if (!ValidateBeginAccess(write_access))
+  if (!ValidateBeginAccess(write_access)) {
+    // TODO(crbug.com/1430941): Remove after fixing overlay access crash.
+    base::debug::DumpWithoutCrashing();
     return false;
+  }
 
   // If read fences or write fence are present, shared handle should be too.
   DCHECK((read_fences_.empty() && !write_fence_) || dxgi_shared_handle_state_);
@@ -976,6 +980,8 @@
   // no dependency between concurrent reads and instead wait for the last write.
   if (write_fence_ && !write_fence_->WaitD3D11(d3d11_device_)) {
     DLOG(ERROR) << "Failed to wait for write fence";
+    // TODO(crbug.com/1430941): Remove after fixing overlay access crash.
+    base::debug::DumpWithoutCrashing();
     return false;
   }
   if (write_access) {
@@ -983,6 +989,8 @@
     for (const auto& fence : read_fences_) {
       if (!fence->WaitD3D11(d3d11_device_)) {
         DLOG(ERROR) << "Failed to wait for read fence";
+        // TODO(crbug.com/1430941): Remove after fixing overlay access crash.
+        base::debug::DumpWithoutCrashing();
         return false;
       }
     }
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 7a49807..50bde77 100644
--- a/gpu/command_buffer/service/shared_image/shared_image_representation.cc
+++ b/gpu/command_buffer/service/shared_image/shared_image_representation.cc
@@ -408,12 +408,17 @@
 OverlayImageRepresentation::BeginScopedReadAccess() {
   if (!IsCleared()) {
     LOG(ERROR) << "Attempt to read from an uninitialized SharedImage";
+    // TODO(crbug.com/1430941): Remove after fixing overlay access crash.
+    base::debug::DumpWithoutCrashing();
     return nullptr;
   }
 
   gfx::GpuFenceHandle acquire_fence;
-  if (!BeginReadAccess(acquire_fence))
+  if (!BeginReadAccess(acquire_fence)) {
+    // TODO(crbug.com/1430941): Remove after fixing overlay access crash.
+    base::debug::DumpWithoutCrashing();
     return nullptr;
+  }
 
   backing()->OnReadSucceeded();
 
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd
index 033c254..373cc3a 100644
--- a/ios/chrome/app/strings/ios_strings.grd
+++ b/ios/chrome/app/strings/ios_strings.grd
@@ -1931,6 +1931,12 @@
       <message name="IDS_IOS_PASSWORD_BOTTOM_SHEET_NO_THANKS" desc="The action button to dismiss the password bottom sheet and revert to using the keyboard to fill in username and password information on the webpage.">
         No Thanks
       </message>
+      <message name="IDS_IOS_PASSWORD_BOTTOM_SHEET_PASSWORD_MANAGER" desc="The password bottom sheet's long press menu item to open the password manager.">
+        Password Manager
+      </message>
+      <message name="IDS_IOS_PASSWORD_BOTTOM_SHEET_SHOW_DETAILS" desc="The password bottom sheet's long press menu item to open the password details page, which displays more information, like username, password and associated website.">
+        Show Details
+      </message>
       <message name="IDS_IOS_PRICE_NOTIFICATIONS_PRICE_TRACK_CHIP" desc="Acessibility label to describe the UI which displays a product's price in the Price Tracking Item UI.">
           Price
       </message>
@@ -3126,7 +3132,7 @@
       <message name="IDS_IOS_SETTINGS_PRIVACY_TITLE" desc="Title for the Privacy and Security preferences.">
         Privacy and Security
       </message>
-      <message name="IDS_IOS_SETTINGS_SAFETY_CHECK_PASSWORDS_TITLE" desc="Title for the passwords element of safety check" meaning="Row title to access the passowrd check subpage if a probelm is found with user's saved passwords [CHAR_LIMIT=20]">
+      <message name="IDS_IOS_SETTINGS_SAFETY_CHECK_PASSWORDS_TITLE" desc="Title for the passwords element of safety check" meaning="Row title to access the password check subpage if a probelm is found with user's saved passwords [CHAR_LIMIT=20]">
         Passwords
       </message>
       <message name="IDS_IOS_SETTINGS_SAFETY_CHECK_PASSWORDS_DESCRIPTION" desc="Description text on the password element describing what the password check does.">
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_PASSWORD_BOTTOM_SHEET_PASSWORD_MANAGER.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_PASSWORD_BOTTOM_SHEET_PASSWORD_MANAGER.png.sha1
new file mode 100644
index 0000000..b227fb1
--- /dev/null
+++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_PASSWORD_BOTTOM_SHEET_PASSWORD_MANAGER.png.sha1
@@ -0,0 +1 @@
+67d70e4ed9fee06f88c698fdbcf5c0f6f9f2a95e
\ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_PASSWORD_BOTTOM_SHEET_SHOW_DETAILS.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_PASSWORD_BOTTOM_SHEET_SHOW_DETAILS.png.sha1
new file mode 100644
index 0000000..b227fb1
--- /dev/null
+++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_PASSWORD_BOTTOM_SHEET_SHOW_DETAILS.png.sha1
@@ -0,0 +1 @@
+67d70e4ed9fee06f88c698fdbcf5c0f6f9f2a95e
\ No newline at end of file
diff --git a/ios/chrome/app/variations_app_state_agent.mm b/ios/chrome/app/variations_app_state_agent.mm
index 6851a3e2..433c678 100644
--- a/ios/chrome/app/variations_app_state_agent.mm
+++ b/ios/chrome/app/variations_app_state_agent.mm
@@ -293,7 +293,7 @@
 
 #pragma mark - IOSChromeVariationsSeedFetcherDelegate
 
-- (void)didFetchSeedSuccess:(BOOL)succeeded {
+- (void)variationsSeedFetcherDidCompleteFetchWithSuccess:(BOOL)success {
   DCHECK_EQ(_group, IOSChromeVariationsGroup::kEnabled);
   DCHECK_LE(self.appState.initStage, InitStageVariationsSeed);
   _seedFetchCompleted = YES;
diff --git a/ios/chrome/app/variations_app_state_agent_unittest.mm b/ios/chrome/app/variations_app_state_agent_unittest.mm
index 0259c53..c6e6957 100644
--- a/ios/chrome/app/variations_app_state_agent_unittest.mm
+++ b/ios/chrome/app/variations_app_state_agent_unittest.mm
@@ -112,7 +112,8 @@
 
   // Simulate that the fetcher has completed fetching.
   void SimulateFetchCompletion(VariationsAppStateAgent* agent) {
-    [mock_fetcher_.delegate didFetchSeedSuccess:NO];
+    [mock_fetcher_.delegate
+        variationsSeedFetcherDidCompleteFetchWithSuccess:NO];
   }
 
   // Setter of the current stage of the mock app state. This also invokes
diff --git a/ios/chrome/browser/flags/BUILD.gn b/ios/chrome/browser/flags/BUILD.gn
index 08c133b..a5121b6 100644
--- a/ios/chrome/browser/flags/BUILD.gn
+++ b/ios/chrome/browser/flags/BUILD.gn
@@ -28,6 +28,7 @@
     "//components/feed:feature_list",
     "//components/flags_ui",
     "//components/flags_ui:switches",
+    "//components/history/core/browser",
     "//components/invalidation/impl:feature_list",
     "//components/ntp_tiles",
     "//components/omnibox/browser",
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm
index 63e46891..c64e343 100644
--- a/ios/chrome/browser/flags/about_flags.mm
+++ b/ios/chrome/browser/flags/about_flags.mm
@@ -40,6 +40,7 @@
 #import "components/flags_ui/feature_entry_macros.h"
 #import "components/flags_ui/flags_storage.h"
 #import "components/flags_ui/flags_ui_switches.h"
+#import "components/history/core/browser/features.h"
 #import "components/invalidation/impl/invalidation_switches.h"
 #import "components/ntp_tiles/features.h"
 #import "components/ntp_tiles/switches.h"
@@ -1031,6 +1032,9 @@
      flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(
          optimization_guide::features::kOptimizationTargetPrediction)},
+    {"sync-segments-data", flag_descriptions::kSyncSegmentsDataName,
+     flag_descriptions::kSyncSegmentsDataDescription, flags_ui::kOsIos,
+     FEATURE_VALUE_TYPE(history::kSyncSegmentsData)},
     {"sync-standalone-invalidations", flag_descriptions::kSyncInvalidationsName,
      flag_descriptions::kSyncInvalidationsDescription, flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(::syncer::kUseSyncInvalidations)},
diff --git a/ios/chrome/browser/flags/ios_chrome_field_trials.mm b/ios/chrome/browser/flags/ios_chrome_field_trials.mm
index 38f5fa9..b144cb0 100644
--- a/ios/chrome/browser/flags/ios_chrome_field_trials.mm
+++ b/ios/chrome/browser/flags/ios_chrome_field_trials.mm
@@ -11,6 +11,7 @@
 #import "ios/chrome/browser/application_context/application_context.h"
 #import "ios/chrome/browser/paths/paths.h"
 #import "ios/chrome/browser/ui/ntp/new_tab_page_retention_field_trial.h"
+#import "ios/chrome/browser/ui/ntp/synced_segments_field_trial.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -40,4 +41,7 @@
   new_tab_page_retention_field_trial::Create(
       entropy_providers.low_entropy(), feature_list,
       GetApplicationContext()->GetLocalState());
+  synced_segments_field_trial::Create(entropy_providers.low_entropy(),
+                                      feature_list,
+                                      GetApplicationContext()->GetLocalState());
 }
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
index 62a386a..1c41f9d 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -953,6 +953,11 @@
 const char kSyncSandboxDescription[] =
     "Connects to the testing server for Chrome Sync.";
 
+const char kSyncSegmentsDataName[] = "Use synced segments data";
+const char kSyncSegmentsDataDescription[] =
+    "Enables history's segments to include foreign visits from syncing "
+    "devices.";
+
 const char kSynthesizedRestoreSessionName[] =
     "Use a synthesized native WKWebView sesion restoration (iOS15 only).";
 const char kSynthesizedRestoreSessionDescription[] =
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
index 740ae629..c484b44 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -846,6 +846,11 @@
 extern const char kSyncSandboxName[];
 extern const char kSyncSandboxDescription[];
 
+// Title and description for the flag to control if history's segments should
+// include foreign visits from syncing devices.
+extern const char kSyncSegmentsDataName[];
+extern const char kSyncSegmentsDataDescription[];
+
 // Title and description for the flag to synthesize native restore web states.
 extern const char kSynthesizedRestoreSessionName[];
 extern const char kSynthesizedRestoreSessionDescription[];
diff --git a/ios/chrome/browser/prefs/browser_prefs.mm b/ios/chrome/browser/prefs/browser_prefs.mm
index 0269032d..dd437d19 100644
--- a/ios/chrome/browser/prefs/browser_prefs.mm
+++ b/ios/chrome/browser/prefs/browser_prefs.mm
@@ -76,6 +76,7 @@
 #import "ios/chrome/browser/ui/first_run/trending_queries_field_trial.h"
 #import "ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.h"
 #import "ios/chrome/browser/ui/ntp/new_tab_page_retention_field_trial.h"
+#import "ios/chrome/browser/ui/ntp/synced_segments_field_trial.h"
 #import "ios/chrome/browser/voice/voice_search_prefs_registration.h"
 #import "ios/chrome/browser/web/font_size/font_size_tab_helper.h"
 #import "ios/web/common/features.h"
@@ -140,6 +141,7 @@
   variations::VariationsService::RegisterPrefs(registry);
   trending_queries_field_trial::RegisterLocalStatePrefs(registry);
   new_tab_page_retention_field_trial::RegisterLocalStatePrefs(registry);
+  synced_segments_field_trial::RegisterLocalStatePrefs(registry);
   component_updater::RegisterComponentUpdateServicePrefs(registry);
   component_updater::AutofillStatesComponentInstallerPolicy::RegisterPrefs(
       registry);
diff --git a/ios/chrome/browser/ui/bring_android_tabs/BUILD.gn b/ios/chrome/browser/ui/bring_android_tabs/BUILD.gn
index 45e18c2..cadb0e2a 100644
--- a/ios/chrome/browser/ui/bring_android_tabs/BUILD.gn
+++ b/ios/chrome/browser/ui/bring_android_tabs/BUILD.gn
@@ -19,7 +19,9 @@
   deps = [
     ":bring_android_tabs_ui",
     ":bring_android_tabs_ui_swift",
+    ":constants",
     "//base",
+    "//components/favicon/core",
     "//ios/chrome/browser/bring_android_tabs",
     "//ios/chrome/browser/bring_android_tabs:features",
     "//ios/chrome/browser/bring_android_tabs:metrics",
@@ -29,6 +31,7 @@
     "//ios/chrome/browser/net:crurl",
     "//ios/chrome/browser/shared/coordinator/chrome_coordinator",
     "//ios/chrome/browser/shared/public/commands",
+    "//ios/chrome/browser/shared/ui/list_model",
     "//ios/chrome/browser/shared/ui/table_view",
     "//ios/chrome/browser/synced_sessions",
     "//ios/chrome/browser/url_loading",
@@ -41,11 +44,27 @@
   configs += [ "//build/config/compiler:enable_arc" ]
   sources = [
     "bring_android_tabs_prompt_view_controller_delegate.h",
+    "tab_list_from_android_consumer.h",
+    "tab_list_from_android_table_view_item.h",
+    "tab_list_from_android_table_view_item.mm",
+    "tab_list_from_android_view_controller.h",
+    "tab_list_from_android_view_controller.mm",
     "tab_list_from_android_view_controller_delegate.h",
   ]
   deps = [
     ":constants",
     "//base",
+    "//components/url_formatter",
+    "//ios/chrome/app/strings",
+    "//ios/chrome/browser/bring_android_tabs",
+    "//ios/chrome/browser/net:crurl",
+    "//ios/chrome/browser/shared/ui/list_model",
+    "//ios/chrome/browser/shared/ui/table_view",
+    "//ios/chrome/browser/shared/ui/table_view:utils",
+    "//ios/chrome/browser/synced_sessions",
+    "//ios/chrome/common/ui/colors",
+    "//ios/chrome/common/ui/favicon",
+    "//ios/chrome/common/ui/table_view:cells_constants",
   ]
 }
 
diff --git a/ios/chrome/browser/ui/bring_android_tabs/constants.h b/ios/chrome/browser/ui/bring_android_tabs/constants.h
index 67afece..bf3ea55 100644
--- a/ios/chrome/browser/ui/bring_android_tabs/constants.h
+++ b/ios/chrome/browser/ui/bring_android_tabs/constants.h
@@ -15,4 +15,14 @@
 // view controller.
 extern NSString* const kBringAndroidTabsPromptBottomMessageAXId;
 
+// Accessibility identifier for the "Bring Android Tabs" tab list
+// view controller.
+extern NSString* const kBringAndroidTabsPromptTabListAXId;
+
+// Size of the favicons in the "Bring Android Tabs" tab list.
+extern CGFloat const kBringAndroidTabsFaviconSize;
+
+// Height of the table rows in the "Bring Android Tabs" tab list.
+extern CGFloat const kTabListFromAndroidCellHeight;
+
 #endif  // IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/bring_android_tabs/constants.mm b/ios/chrome/browser/ui/bring_android_tabs/constants.mm
index c15d52cc..ff9cc96 100644
--- a/ios/chrome/browser/ui/bring_android_tabs/constants.mm
+++ b/ios/chrome/browser/ui/bring_android_tabs/constants.mm
@@ -13,3 +13,10 @@
 
 NSString* const kBringAndroidTabsPromptBottomMessageAXId =
     @"kBringAndroidTabsPromptBottomMessageAccessibilityIdentifier";
+
+NSString* const kBringAndroidTabsPromptTabListAXId =
+    @"kBringAndroidTabsPromptTabListAccessibilityIdentifier";
+
+CGFloat const kBringAndroidTabsFaviconSize = 48;
+
+CGFloat const kTabListFromAndroidCellHeight = 78.0;
diff --git a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_consumer.h b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_consumer.h
new file mode 100644
index 0000000..370981a8
--- /dev/null
+++ b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_consumer.h
@@ -0,0 +1,20 @@
+// 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 IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_TAB_LIST_FROM_ANDROID_CONSUMER_H_
+#define IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_TAB_LIST_FROM_ANDROID_CONSUMER_H_
+
+#import <Foundation/Foundation.h>
+
+@class TabListFromAndroidTableViewItem;
+
+// Consumer for the Tab List From Android view.
+@protocol TabListFromAndroidConsumer
+
+// Sets the `items` displayed by this consumer.
+- (void)setTabListItems:(NSArray<TabListFromAndroidTableViewItem*>*)items;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_TAB_LIST_FROM_ANDROID_CONSUMER_H_
diff --git a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_coordinator.mm b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_coordinator.mm
index 493b5bb..76c991c7 100644
--- a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_coordinator.mm
+++ b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_coordinator.mm
@@ -4,14 +4,19 @@
 
 #import "ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_coordinator.h"
 
+#import "components/favicon/core/favicon_service.h"
+#import "components/keyed_service/core/service_access_type.h"
 #import "ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service.h"
 #import "ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service_factory.h"
 #import "ios/chrome/browser/browser_state/chrome_browser_state.h"
+#import "ios/chrome/browser/favicon/favicon_service_factory.h"
 #import "ios/chrome/browser/favicon/ios_chrome_favicon_loader_factory.h"
 #import "ios/chrome/browser/main/browser.h"
 #import "ios/chrome/browser/shared/public/commands/bring_android_tabs_commands.h"
 #import "ios/chrome/browser/shared/ui/table_view/chrome_table_view_controller.h"
+#import "ios/chrome/browser/shared/ui/table_view/table_view_navigation_controller.h"
 #import "ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_mediator.h"
+#import "ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller.h"
 #import "ios/chrome/browser/url_loading/url_loading_browser_agent.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -21,9 +26,8 @@
 @implementation TabListFromAndroidCoordinator {
   // Main mediator for this coordinator.
   TabListFromAndroidMediator* _mediator;
-
-  // Main view controller for this coordinator.
-  ChromeTableViewController* _viewController;
+  // Navigation controller displaying TabListFromAndroidViewController.
+  TableViewNavigationController* _navigationController;
 }
 
 - (void)start {
@@ -38,20 +42,32 @@
                                           GetForBrowserState(
                                               self.browser->GetBrowserState())];
 
-  // TODO(crbug.com/1418120): Create table view controller.
-  /*_viewController = [ChromeTableViewController
-      initWithBringAndroidTabsService:service
-            delegate:_mediator
-      commandHandler:HandlerForProtocol(self.browser->GetCommandDispatcher(),
-                                        BringAndroidTabsCommands)];*/
+  TabListFromAndroidViewController* tableViewController =
+      [[TabListFromAndroidViewController alloc] init];
+  tableViewController.delegate = _mediator;
+  tableViewController.faviconDataSource = _mediator;
+  _mediator.consumer = tableViewController;
+
+  _navigationController =
+      [[TableViewNavigationController alloc] initWithTable:tableViewController];
+  [_navigationController
+      setModalPresentationStyle:UIModalPresentationFormSheet];
+  _navigationController.toolbarHidden = YES;
+  _navigationController.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;
+  _navigationController.presentationController.delegate = tableViewController;
+
+  [self.baseViewController presentViewController:_navigationController
+                                        animated:YES
+                                      completion:nil];
 }
 
 - (void)stop {
   [super stop];
-  [_viewController.presentingViewController dismissViewControllerAnimated:YES
-                                                               completion:nil];
+  [_navigationController.presentingViewController
+      dismissViewControllerAnimated:YES
+                         completion:nil];
   _mediator = nil;
-  _viewController = nil;
+  _navigationController = nil;
 }
 
 @end
diff --git a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_mediator.h b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_mediator.h
index 4f2cfef..e331397 100644
--- a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_mediator.h
+++ b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_mediator.h
@@ -12,12 +12,16 @@
 
 class BringAndroidTabsToIOSService;
 class FaviconLoader;
+@protocol TabListFromAndroidConsumer;
 class UrlLoadingBrowserAgent;
 
 // Mediator for the "Tab List From Android" table.
 @interface TabListFromAndroidMediator
-    : NSObject <TabListFromAndroidViewControllerDelegate,
-                TableViewFaviconDataSource>
+    : NSObject <TableViewFaviconDataSource,
+                TabListFromAndroidViewControllerDelegate>
+
+// The main consumer for this mediator.
+@property(nonatomic, weak) id<TabListFromAndroidConsumer> consumer;
 
 // Designated initializer for the mediator. `service` is used to load the user's
 // tabs to bring to iOS from their Android device.
diff --git a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_mediator.mm b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_mediator.mm
index 48c811c..985bfe70 100644
--- a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_mediator.mm
+++ b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_mediator.mm
@@ -5,11 +5,17 @@
 #import "ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_mediator.h"
 
 #import "base/metrics/histogram_functions.h"
+#import "base/strings/sys_string_conversions.h"
 #import "ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service.h"
 #import "ios/chrome/browser/bring_android_tabs/metrics.h"
 #import "ios/chrome/browser/favicon/favicon_loader.h"
 #import "ios/chrome/browser/net/crurl.h"
+#import "ios/chrome/browser/shared/ui/list_model/list_model.h"
+#import "ios/chrome/browser/synced_sessions/distant_tab.h"
 #import "ios/chrome/browser/synced_sessions/synced_sessions_util.h"
+#import "ios/chrome/browser/ui/bring_android_tabs/constants.h"
+#import "ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_consumer.h"
+#import "ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_table_view_item.h"
 #import "ios/chrome/browser/url_loading/url_loading_browser_agent.h"
 #import "ios/chrome/browser/url_loading/url_loading_params.h"
 #import "ios/chrome/common/ui/favicon/favicon_constants.h"
@@ -18,6 +24,14 @@
 #error "This file requires ARC support."
 #endif
 
+namespace {
+
+typedef NS_ENUM(NSInteger, ItemType) {
+  TabItemType = kItemTypeEnumZero,
+};
+
+}  // namespace
+
 @implementation TabListFromAndroidMediator {
   // Keyed service to retrieve active tabs from Android.
   BringAndroidTabsToIOSService* _bringAndroidTabsService;
@@ -40,13 +54,18 @@
   return self;
 }
 
+- (void)setConsumer:(id<TabListFromAndroidConsumer>)consumer {
+  _consumer = consumer;
+  [_consumer setTabListItems:[self tableViewItemArray]];
+}
+
 #pragma mark - TableViewFaviconDataSource
 
 - (void)faviconForPageURL:(CrURL*)URL
                completion:(void (^)(FaviconAttributes*))completion {
   _faviconLoader->FaviconForPageUrl(
-      URL.gurl, kDesiredMediumFaviconSizePt, kMinFaviconSizePt,
-      /*fallback_to_google_server=*/false, ^(FaviconAttributes* attributes) {
+      URL.gurl, kBringAndroidTabsFaviconSize, kMinFaviconSizePt,
+      /*fallback_to_google_server=*/true, ^(FaviconAttributes* attributes) {
         completion(attributes);
       });
 }
@@ -54,14 +73,15 @@
 #pragma mark - TabListFromAndroidViewControllerDelegate
 
 - (void)tabListFromAndroidViewControllerDidDismissWithSwipe:(BOOL)swiped
-                                     numberOfDeselectedTabs:(int)count {
+                                     numberOfDeselectedTabs:
+                                         (int)countDeselected {
   bring_android_tabs::TabsListActionType action =
       swiped ? bring_android_tabs::TabsListActionType::kSwipeDown
              : bring_android_tabs::TabsListActionType::kCancel;
   base::UmaHistogramEnumeration(bring_android_tabs::kTabListActionHistogramName,
                                 action);
   base::UmaHistogramCounts1000(
-      bring_android_tabs::kDeselectedTabCountHistogramName, count);
+      bring_android_tabs::kDeselectedTabCountHistogramName, countDeselected);
   // The user journey to bring recent tabs on Android to iOS has finished.
   // Reload the service to update/clear the tabs.
   _bringAndroidTabsService->LoadTabs();
@@ -86,4 +106,24 @@
   }
 }
 
+#pragma mark - Private
+
+// Returns an array of table view items corresponding to the user's tabs from
+// Android.
+- (NSArray<TabListFromAndroidTableViewItem*>*)tableViewItemArray {
+  NSMutableArray<TabListFromAndroidTableViewItem*>* itemArray =
+      [[NSMutableArray alloc] init];
+  for (size_t idx = 0; idx < _bringAndroidTabsService->GetNumberOfAndroidTabs();
+       idx++) {
+    synced_sessions::DistantTab* distantTab =
+        _bringAndroidTabsService->GetTabAtIndex(idx);
+    TabListFromAndroidTableViewItem* tabListItem =
+        [[TabListFromAndroidTableViewItem alloc] initWithType:TabItemType];
+    tabListItem.title = base::SysUTF16ToNSString(distantTab->title);
+    tabListItem.URL = [[CrURL alloc] initWithGURL:distantTab->virtual_url];
+    [itemArray addObject:tabListItem];
+  }
+  return itemArray;
+}
+
 @end
diff --git a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_table_view_item.h b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_table_view_item.h
new file mode 100644
index 0000000..733f444
--- /dev/null
+++ b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_table_view_item.h
@@ -0,0 +1,51 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_TAB_LIST_FROM_ANDROID_TABLE_VIEW_ITEM_H_
+#define IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_TAB_LIST_FROM_ANDROID_TABLE_VIEW_ITEM_H_
+
+#import <UIKit/UIKit.h>
+
+#import "ios/chrome/browser/shared/ui/table_view/cells/table_view_cell.h"
+#import "ios/chrome/browser/shared/ui/table_view/cells/table_view_item.h"
+
+@class CrURL;
+@class FaviconView;
+
+// TabListFromAndroidTableViewItem contains the model data for a
+// TabListFromAndroidTableViewCell.
+@interface TabListFromAndroidTableViewItem : TableViewItem
+
+// The title of the page at `URL`.
+@property(nonatomic, readwrite, copy) NSString* title;
+
+// CrURL from which the cell will retrieve a favicon and display the host name.
+@property(nonatomic, readwrite, strong) CrURL* URL;
+
+// Identifier to match a TabListFromAndroidTableViewItem with its
+// TabListFromAndroidTableViewCell.
+@property(nonatomic, readonly) NSString* uniqueIdentifier;
+
+@end
+
+// TabListFromAndroidTableViewCell is used in the Bring Android Tabs prompt.
+// Contains a favicon, title, and URL.
+@interface TabListFromAndroidTableViewCell : TableViewCell
+
+// The imageview that is displayed on the leading edge of the cell.  This
+// contains a favicon composited on top of an off-white background.
+@property(nonatomic, readwrite, strong) FaviconView* faviconView;
+
+// The cell title.
+@property(nonatomic, readonly, strong) UILabel* titleLabel;
+
+// The host URL associated with this cell.
+@property(nonatomic, readonly, strong) UILabel* URLLabel;
+
+// Unique identifier that matches with one TabListFromAndroidTableViewItem.
+@property(nonatomic, strong) NSString* cellUniqueIdentifier;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_TAB_LIST_FROM_ANDROID_TABLE_VIEW_ITEM_H_
diff --git a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_table_view_item.mm b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_table_view_item.mm
new file mode 100644
index 0000000..ea8c02cc
--- /dev/null
+++ b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_table_view_item.mm
@@ -0,0 +1,217 @@
+// 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 "ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_table_view_item.h"
+
+#import "base/mac/foundation_util.h"
+#import "base/strings/sys_string_conversions.h"
+#import "components/url_formatter/elide_url.h"
+#import "ios/chrome/browser/net/crurl.h"
+#import "ios/chrome/browser/ui/bring_android_tabs/constants.h"
+#import "ios/chrome/common/ui/colors/semantic_color_names.h"
+#import "ios/chrome/common/ui/favicon/favicon_container_view.h"
+#import "ios/chrome/common/ui/favicon/favicon_view.h"
+#import "ios/chrome/common/ui/table_view/table_view_cells_constants.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@implementation TabListFromAndroidTableViewItem
+
+- (instancetype)initWithType:(NSInteger)type {
+  if (self = [super initWithType:type]) {
+    self.cellClass = [TabListFromAndroidTableViewCell class];
+  }
+  return self;
+}
+
+- (void)configureCell:(TableViewCell*)tableCell
+           withStyler:(ChromeTableViewStyler*)styler {
+  [super configureCell:tableCell withStyler:styler];
+
+  TabListFromAndroidTableViewCell* cell =
+      base::mac::ObjCCastStrict<TabListFromAndroidTableViewCell>(tableCell);
+  cell.titleLabel.text = [self titleLabelText];
+  cell.URLLabel.text = [self URLLabelText];
+  cell.cellUniqueIdentifier = self.uniqueIdentifier;
+  cell.accessibilityTraits |= UIAccessibilityTraitButton;
+}
+
+- (NSString*)uniqueIdentifier {
+  return self.URL ? base::SysUTF8ToNSString(self.URL.gurl.host()) : @"";
+}
+
+#pragma mark - Private
+
+// Returns the text to use when configuring a TabListFromAndroidTableViewCell's
+// title label.
+- (NSString*)titleLabelText {
+  if (self.title.length) {
+    return self.title;
+  }
+  if (!self.URL) {
+    return @"";
+  }
+  NSString* hostname = [self displayedURL];
+  if (hostname.length) {
+    return hostname;
+  }
+  // Backup in case host returns nothing (e.g. about:blank).
+  return base::SysUTF8ToNSString(self.URL.gurl.spec());
+}
+
+// Returns the text to use when configuring a TabListFromAndroidTableViewCell's
+// URL label.
+- (NSString*)URLLabelText {
+  return self.URL ? [self displayedURL] : @"";
+}
+
+// Returns a formatted URL text.
+- (NSString*)displayedURL {
+  return base::SysUTF16ToNSString(
+      url_formatter::
+          FormatUrlForDisplayOmitSchemePathTrivialSubdomainsAndMobilePrefix(
+              self.URL.gurl));
+}
+
+@end
+
+@implementation TabListFromAndroidTableViewCell
+
+- (instancetype)initWithStyle:(UITableViewCellStyle)style
+              reuseIdentifier:(NSString*)reuseIdentifier {
+  if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
+    _faviconView = [[FaviconView alloc] init];
+    _titleLabel = [[UILabel alloc] init];
+    _URLLabel = [[UILabel alloc] init];
+    self.isAccessibilityElement = YES;
+  }
+  return self;
+}
+
+#pragma mark - UIView
+
+- (void)willMoveToSuperview:(UIView*)newSuperview {
+  [super willMoveToSuperview:newSuperview];
+
+  [self createSubviews];
+}
+
+#pragma mark - Accessors
+
+- (NSString*)accessibilityLabel {
+  NSString* accessibilityLabel = self.titleLabel.text;
+  accessibilityLabel = [NSString
+      stringWithFormat:@"%@, %@", accessibilityLabel, self.URLLabel.text];
+  return accessibilityLabel;
+}
+
+- (NSArray<NSString*>*)accessibilityUserInputLabels {
+  NSMutableArray<NSString*>* userInputLabels = [[NSMutableArray alloc] init];
+  if (self.titleLabel.text) {
+    [userInputLabels addObject:self.titleLabel.text];
+  }
+  return userInputLabels;
+}
+
+- (NSString*)accessibilityIdentifier {
+  return self.titleLabel.text;
+}
+
+#pragma mark - Private
+
+// Creates and lays out the favicon, title, and URL subviews.
+- (void)createSubviews {
+  // Return if the subviews have already been created and added.
+  if (self.contentView.subviews.count != 0) {
+    return;
+  }
+  FaviconContainerView* faviconContainerView = [self faviconContainerView];
+  UIStackView* verticalStack = [self stackView];
+
+  UIView* contentView = self.contentView;
+  contentView.frame = self.frame;
+  [contentView addSubview:faviconContainerView];
+  [contentView addSubview:verticalStack];
+
+  NSLayoutConstraint* heightConstraint = [contentView.heightAnchor
+      constraintGreaterThanOrEqualToConstant:kTabListFromAndroidCellHeight];
+  // Don't set the priority to required to avoid clashing with the estimated
+  // height.
+  heightConstraint.priority = UILayoutPriorityRequired - 1;
+
+  CGFloat faviconContainerSize = kBringAndroidTabsFaviconSize + 3;
+
+  [NSLayoutConstraint activateConstraints:@[
+    [faviconContainerView.leadingAnchor
+        constraintEqualToAnchor:contentView.leadingAnchor
+                       constant:kTableViewHorizontalSpacing],
+    [faviconContainerView.centerYAnchor
+        constraintEqualToAnchor:contentView.centerYAnchor],
+    [faviconContainerView.widthAnchor
+        constraintEqualToConstant:faviconContainerSize],
+    [faviconContainerView.heightAnchor
+        constraintEqualToAnchor:faviconContainerView.widthAnchor],
+
+    [_faviconView.widthAnchor
+        constraintEqualToConstant:kBringAndroidTabsFaviconSize],
+    [_faviconView.heightAnchor
+        constraintEqualToAnchor:_faviconView.widthAnchor],
+    [_faviconView.centerYAnchor
+        constraintEqualToAnchor:faviconContainerView.centerYAnchor],
+    [_faviconView.centerXAnchor
+        constraintEqualToAnchor:faviconContainerView.centerXAnchor],
+
+    [verticalStack.leadingAnchor
+        constraintEqualToAnchor:faviconContainerView.trailingAnchor
+                       constant:kTableViewSubViewHorizontalSpacing],
+    [verticalStack.trailingAnchor
+        constraintEqualToAnchor:contentView.trailingAnchor
+                       constant:-kTableViewHorizontalSpacing],
+    [verticalStack.centerYAnchor
+        constraintEqualToAnchor:contentView.centerYAnchor],
+    [verticalStack.topAnchor
+        constraintGreaterThanOrEqualToAnchor:contentView.topAnchor
+                                    constant:
+                                        kTableViewTwoLabelsCellVerticalSpacing],
+    [verticalStack.bottomAnchor
+        constraintLessThanOrEqualToAnchor:contentView.bottomAnchor
+                                 constant:
+                                     -kTableViewTwoLabelsCellVerticalSpacing],
+    heightConstraint
+  ]];
+}
+
+// Creates and returns the vertical stack view. The stack consists of a title
+// and URL.
+- (UIStackView*)stackView {
+  _titleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
+  _titleLabel.adjustsFontForContentSizeCategory = YES;
+  _titleLabel.numberOfLines = 2;
+  _URLLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote];
+  _URLLabel.adjustsFontForContentSizeCategory = YES;
+  _URLLabel.textColor = [UIColor colorNamed:kTextSecondaryColor];
+
+  UIStackView* verticalStack = [[UIStackView alloc]
+      initWithArrangedSubviews:@[ _titleLabel, _URLLabel ]];
+  verticalStack.axis = UILayoutConstraintAxisVertical;
+  verticalStack.translatesAutoresizingMaskIntoConstraints = NO;
+  return verticalStack;
+}
+
+// Creates and returns the container for the favicon view.
+- (FaviconContainerView*)faviconContainerView {
+  FaviconContainerView* faviconContainerView =
+      [[FaviconContainerView alloc] init];
+  [faviconContainerView addSubview:_faviconView];
+  faviconContainerView.translatesAutoresizingMaskIntoConstraints = NO;
+  _faviconView.translatesAutoresizingMaskIntoConstraints = NO;
+  _faviconView.contentMode = UIViewContentModeScaleAspectFill;
+  _faviconView.clipsToBounds = YES;
+  _faviconView.layer.masksToBounds = YES;
+  return faviconContainerView;
+}
+
+@end
diff --git a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller.h b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller.h
new file mode 100644
index 0000000..d84e2a4
--- /dev/null
+++ b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller.h
@@ -0,0 +1,34 @@
+// 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 IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_TAB_LIST_FROM_ANDROID_VIEW_CONTROLLER_H_
+#define IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_TAB_LIST_FROM_ANDROID_VIEW_CONTROLLER_H_
+
+#import "ios/chrome/browser/shared/ui/table_view/chrome_table_view_controller.h"
+#import "ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_consumer.h"
+
+@protocol TableViewFaviconDataSource;
+@protocol TabListFromAndroidViewControllerDelegate;
+
+// Table view controller for the "Bring Android Tabs" tab list.
+@interface TabListFromAndroidViewController
+    : ChromeTableViewController <TabListFromAndroidConsumer,
+                                 UIAdaptivePresentationControllerDelegate>
+
+// Delegate protocol that handles model updates on interaction.
+@property(nonatomic, weak) id<TabListFromAndroidViewControllerDelegate>
+    delegate;
+
+// Data source for favicon images.
+@property(nonatomic, weak) id<TableViewFaviconDataSource> faviconDataSource;
+
+// Designated initializer for this view controller.
+- (instancetype)init NS_DESIGNATED_INITIALIZER;
+
+// Unavailable initializer.
+- (instancetype)initWithStyle:(UITableViewStyle)style NS_UNAVAILABLE;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_TAB_LIST_FROM_ANDROID_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller.mm b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller.mm
new file mode 100644
index 0000000..311ca49
--- /dev/null
+++ b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller.mm
@@ -0,0 +1,219 @@
+// 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 "ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller.h"
+
+#import "base/check_op.h"
+#import "base/i18n/message_formatter.h"
+#import "base/mac/foundation_util.h"
+#import "base/strings/sys_string_conversions.h"
+#import "ios/chrome/browser/net/crurl.h"
+#import "ios/chrome/browser/shared/ui/list_model/list_model.h"
+#import "ios/chrome/browser/shared/ui/table_view/table_view_favicon_data_source.h"
+#import "ios/chrome/browser/shared/ui/table_view/table_view_utils.h"
+#import "ios/chrome/browser/synced_sessions/distant_tab.h"
+#import "ios/chrome/browser/ui/bring_android_tabs/constants.h"
+#import "ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_table_view_item.h"
+#import "ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller_delegate.h"
+#import "ios/chrome/common/ui/favicon/favicon_attributes.h"
+#import "ios/chrome/common/ui/favicon/favicon_view.h"
+#import "ios/chrome/grit/ios_strings.h"
+#import "ui/base/l10n/l10n_util.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace {
+
+typedef NS_ENUM(NSInteger, SectionIdentifier) {
+  TabListSectionIdentifier = kSectionIdentifierEnumZero,
+};
+
+}  // namespace
+
+@implementation TabListFromAndroidViewController
+
+- (instancetype)init {
+  return [super initWithStyle:ChromeTableViewStyle()];
+}
+
+- (void)viewDidLoad {
+  [super viewDidLoad];
+  self.definesPresentationContext = YES;
+  self.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;
+  self.title =
+      l10n_util::GetNSString(IDS_IOS_BRING_ANDROID_TABS_REVIEW_TABLE_TITLE);
+  [self.tableView setDelegate:self];
+  self.tableView.allowsMultipleSelectionDuringEditing = YES;
+  self.tableView.allowsMultipleSelection = YES;
+  [self.tableView
+      setSeparatorInset:UIEdgeInsetsMake(0, kTableViewSeparatorInset, 0, 0)];
+  self.tableView.estimatedRowHeight = kTabListFromAndroidCellHeight;
+  self.navigationItem.leftBarButtonItem = [self navigationCancelButton];
+  self.navigationItem.rightBarButtonItem = [self navigationOpenTabsButton];
+  self.tableView.accessibilityIdentifier = kBringAndroidTabsPromptTabListAXId;
+}
+
+#pragma mark - UITableViewDelegate
+
+- (void)tableView:(UITableView*)tableView
+    didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
+  CHECK_EQ(tableView, self.tableView);
+  TableViewItem* item = [self.tableViewModel itemAtIndexPath:indexPath];
+  item.accessoryType = UITableViewCellAccessoryCheckmark;
+  [self reconfigureCellsForItems:@[ item ]];
+  [self updateOpenTabsButton];
+}
+
+- (void)tableView:(UITableView*)tableView
+    didDeselectRowAtIndexPath:(NSIndexPath*)indexPath {
+  CHECK_EQ(tableView, self.tableView);
+  TableViewItem* item = [self.tableViewModel itemAtIndexPath:indexPath];
+  item.accessoryType = UITableViewCellAccessoryNone;
+  [self reconfigureCellsForItems:@[ item ]];
+  [self updateOpenTabsButton];
+}
+
+- (UITableViewCell*)tableView:(UITableView*)tableView
+        cellForRowAtIndexPath:(NSIndexPath*)indexPath {
+  CHECK_EQ(tableView, self.tableView);
+  UITableViewCell* cell = [super tableView:tableView
+                     cellForRowAtIndexPath:indexPath];
+  cell.selectionStyle = UITableViewCellSelectionStyleNone;
+  [self loadFaviconForCell:cell indexPath:indexPath];
+  return cell;
+}
+
+#pragma mark - UIAdaptivePresentationControllerDelegate
+
+- (void)presentationControllerDidDismiss:
+    (UIPresentationController*)presentationController {
+  int numberDeselected =
+      [self.tableView numberOfRowsInSection:TabListSectionIdentifier] -
+      [self.tableView indexPathsForSelectedRows].count;
+  [_delegate
+      tabListFromAndroidViewControllerDidDismissWithSwipe:YES
+                                   numberOfDeselectedTabs:numberDeselected];
+}
+
+#pragma mark - TabListFromAndroidConsumer
+
+- (void)setTabListItems:(NSArray<TabListFromAndroidTableViewItem*>*)items {
+  [self loadModel];
+
+  [self.tableViewModel addSectionWithIdentifier:TabListSectionIdentifier];
+  for (TabListFromAndroidTableViewItem* item : items) {
+    item.accessoryType = UITableViewCellAccessoryCheckmark;
+    [self.tableViewModel addItem:item
+         toSectionWithIdentifier:TabListSectionIdentifier];
+  }
+  // Tabs are selected by default.
+  NSInteger section = [self.tableViewModel
+      sectionForSectionIdentifier:TabListSectionIdentifier];
+  for (NSInteger index = 0;
+       index < [self.tableViewModel numberOfItemsInSection:section]; index++) {
+    [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:index
+                                                            inSection:section]
+                                animated:NO
+                          scrollPosition:UITableViewScrollPositionNone];
+  }
+
+  [self updateOpenTabsButton];
+}
+
+#pragma mark - Helpers
+
+// Retrieves favicon from FaviconLoader and sets FaviconView in given `cell`.
+- (void)loadFaviconForCell:(UITableViewCell*)cell
+                 indexPath:(NSIndexPath*)indexPath {
+  TableViewItem* item = [self.tableViewModel itemAtIndexPath:indexPath];
+  CHECK(item);
+  CHECK(cell);
+  TabListFromAndroidTableViewItem* tabListItem =
+      base::mac::ObjCCastStrict<TabListFromAndroidTableViewItem>(item);
+  TabListFromAndroidTableViewCell* tabListCell =
+      base::mac::ObjCCastStrict<TabListFromAndroidTableViewCell>(cell);
+
+  NSString* itemIdentifier = tabListItem.uniqueIdentifier;
+  [_faviconDataSource
+      faviconForPageURL:tabListItem.URL
+             completion:^(FaviconAttributes* attributes) {
+               // Only set favicon if the cell hasn't been reused.
+               if ([tabListCell.cellUniqueIdentifier
+                       isEqualToString:itemIdentifier]) {
+                 [tabListCell.faviconView configureWithAttributes:attributes];
+               }
+             }];
+}
+
+// Returns the navigation 'cancel' button.
+- (UIBarButtonItem*)navigationCancelButton {
+  return [[UIBarButtonItem alloc]
+      initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
+                           target:self
+                           action:@selector(cancelButtonTapped)];
+}
+
+// Updates the title and enabled status of the 'Open Tabs' button. This method
+// is called and the button is recreated every time the user selects/de-selects
+// a table row.
+- (void)updateOpenTabsButton {
+  UIBarButtonItem* rightBarButton = self.navigationItem.rightBarButtonItem;
+  rightBarButton.title = [self openTabsButtonTitle];
+  int numberSelectedTabs = [self.tableView indexPathsForSelectedRows].count;
+  if (numberSelectedTabs == 0) {
+    [rightBarButton setEnabled:NO];
+  } else {
+    [rightBarButton setEnabled:YES];
+  }
+}
+
+// Returns the title of the navigation 'Open Tabs' button.
+- (NSString*)openTabsButtonTitle {
+  int numberSelectedTabs = [self.tableView indexPathsForSelectedRows].count;
+  return base::SysUTF16ToNSString(l10n_util::GetPluralStringFUTF16(
+      IDS_IOS_BRING_ANDROID_TABS_REVIEW_TABLE_OPEN_BUTTON, numberSelectedTabs));
+}
+
+// Returns the navigation 'Open Tabs' button.
+- (UIBarButtonItem*)navigationOpenTabsButton {
+  return [[UIBarButtonItem alloc] initWithTitle:[self openTabsButtonTitle]
+                                          style:UIBarButtonItemStylePlain
+                                         target:self
+                                         action:@selector(openButtonTapped)];
+}
+
+// Called when the cancel button is tapped.
+- (void)cancelButtonTapped {
+  int numberDeselected =
+      [self.tableView numberOfRowsInSection:TabListSectionIdentifier] -
+      [self.tableView indexPathsForSelectedRows].count;
+  [_delegate
+      tabListFromAndroidViewControllerDidDismissWithSwipe:NO
+                                   numberOfDeselectedTabs:numberDeselected];
+  [self.presentingViewController dismissViewControllerAnimated:YES
+                                                    completion:nil];
+}
+
+//  Called when the open tabs button is tapped.
+- (void)openButtonTapped {
+  [_delegate tabListFromAndroidViewControllerDidTapOpenButtonWithTabIndices:
+                 [self selectedTabIndices]];
+  [self.presentingViewController dismissViewControllerAnimated:YES
+                                                    completion:nil];
+}
+
+// Returns an array with the indices of the tabs the user has selected. Indices
+// correspond to the indices of the list of user's tabs retrieved from
+// BringAndroidTabsToIOSService.
+- (NSArray<NSNumber*>*)selectedTabIndices {
+  NSMutableArray<NSNumber*>* tabIndices = [[NSMutableArray alloc] init];
+  for (NSIndexPath* indexPath in self.tableView.indexPathsForSelectedRows) {
+    [tabIndices addObject:@(indexPath.row)];
+  }
+  return tabIndices;
+}
+
+@end
diff --git a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller_delegate.h b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller_delegate.h
index 9c33c3a0..d398b354 100644
--- a/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller_delegate.h
+++ b/ios/chrome/browser/ui/bring_android_tabs/tab_list_from_android_view_controller_delegate.h
@@ -10,10 +10,11 @@
 @protocol TabListFromAndroidViewControllerDelegate
 
 // Called when the user dismisses the prompt. If the dismissal is done using a
-// modal swipe, the parameter `swiped` is YES. `count` is the number of tabs the
-// user deselected before dismissal.
+// modal swipe, the parameter `swiped` is YES. `countDeselected` is the number
+// of tabs the user deselected before dismissal.
 - (void)tabListFromAndroidViewControllerDidDismissWithSwipe:(BOOL)swiped
-                                     numberOfDeselectedTabs:(int)count;
+                                     numberOfDeselectedTabs:
+                                         (int)countDeselected;
 
 // Called when the user taps the "open" button. Values in `tabIndices`
 // correspond to the indices of the tabs the user wants to open in the
diff --git a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
index 26571a5d..90f8393 100644
--- a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
@@ -2659,6 +2659,7 @@
 
 #pragma mark - NewTabPageTabHelperDelegate
 
+// TODO(crbug.com/1427128): Have the TabEventsMediator implement this.
 - (void)newTabPageHelperDidChangeVisibility:(NewTabPageTabHelper*)NTPHelper
                                 forWebState:(web::WebState*)webState {
   DCHECK(self.browser);
@@ -2672,16 +2673,15 @@
   }
   NewTabPageCoordinator* NTPCoordinator = self.NTPCoordinator;
   DCHECK(NTPCoordinator);
+  // Handle NTP visibility changes within a web state.
   if (NTPHelper->IsActive()) {
-    // Starting the NTPCoordinator triggers its visibility, so we only
-    // explicitly call `didNavigateToNTP` if the NTP was already started.
-    if (NTPCoordinator.started) {
-      [NTPCoordinator didNavigateToNTP];
-    } else {
+    if (!NTPCoordinator.started) {
       [NTPCoordinator start];
     }
+    [NTPCoordinator didNavigateToNTPInWebState:webState];
   } else {
     [NTPCoordinator didNavigateAwayFromNTP];
+    [NTPCoordinator stopIfNeeded];
   }
   if (self.isActive) {
     [self.viewController displayCurrentTab];
diff --git a/ios/chrome/browser/ui/browser_view/browser_coordinator_unittest.mm b/ios/chrome/browser/ui/browser_view/browser_coordinator_unittest.mm
index 741e6923..3b6db39 100644
--- a/ios/chrome/browser/ui/browser_view/browser_coordinator_unittest.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_coordinator_unittest.mm
@@ -325,7 +325,7 @@
   EXPECT_OCMOCK_VERIFY(mockNTPCoordinator);
 
   // Open another NTP and expect a navigation call.
-  [[mockNTPCoordinator expect] didNavigateToNTP];
+  [[mockNTPCoordinator expect] didNavigateToNTPInWebState:GetActiveWebState()];
   OpenURL(GURL("chrome://newtab/"));
   EXPECT_OCMOCK_VERIFY(mockNTPCoordinator);
 
diff --git a/ios/chrome/browser/ui/browser_view/tab_events_mediator.mm b/ios/chrome/browser/ui/browser_view/tab_events_mediator.mm
index 28816874..62e2508 100644
--- a/ios/chrome/browser/ui/browser_view/tab_events_mediator.mm
+++ b/ios/chrome/browser/ui/browser_view/tab_events_mediator.mm
@@ -111,16 +111,6 @@
 }
 
 - (void)webStateList:(WebStateList*)webStateList
-    didDetachWebState:(web::WebState*)webState
-              atIndex:(int)atIndex {
-  NewTabPageTabHelper* NTPTabHelper =
-      NewTabPageTabHelper::FromWebState(webState);
-  if (NTPTabHelper->IsActive()) {
-    [self stopNTPIfNeeded];
-  }
-}
-
-- (void)webStateList:(WebStateList*)webStateList
     didInsertWebState:(web::WebState*)webState
               atIndex:(int)index
            activating:(BOOL)activating {
@@ -133,10 +123,32 @@
 }
 
 - (void)webStateList:(WebStateList*)webStateList
+    willCloseWebState:(web::WebState*)webState
+              atIndex:(int)atIndex
+           userAction:(BOOL)userAction {
+  // When an NTP web state is closed, check if the coordinator should be
+  // stopped.
+  NewTabPageTabHelper* NTPTabHelper =
+      NewTabPageTabHelper::FromWebState(webState);
+  if (NTPTabHelper->IsActive()) {
+    [self stopNTPIfNeeded];
+  }
+}
+
+- (void)webStateList:(WebStateList*)webStateList
     didChangeActiveWebState:(web::WebState*)newWebState
                 oldWebState:(web::WebState*)oldWebState
                     atIndex:(int)atIndex
                      reason:(ActiveWebStateChangeReason)reason {
+  // If the user is leaving an NTP web state, trigger a visibility change.
+  if (oldWebState && _ntpCoordinator.started) {
+    NewTabPageTabHelper* NTPHelper =
+        NewTabPageTabHelper::FromWebState(oldWebState);
+    if (NTPHelper->IsActive()) {
+      [_ntpCoordinator didNavigateAwayFromNTP];
+    }
+  }
+
   if (reason == ActiveWebStateChangeReason::Inserted) {
     [self didInsertActiveWebState:newWebState];
   }
@@ -150,6 +162,14 @@
     // WebState is showing the NTP. BrowserCoordinator's -setActive: only starts
     // the NTP if it is the active view.
     [self startNTPIfNeededForActiveWebState:newWebState];
+
+    // If the user is entering an NTP web state, trigger a visibility change.
+    NewTabPageTabHelper* NTPHelper =
+        NewTabPageTabHelper::FromWebState(newWebState);
+    if (NTPHelper->IsActive()) {
+      [_ntpCoordinator didNavigateToNTPInWebState:newWebState];
+    }
+
     [self.consumer webStateSelected];
   }
 }
@@ -208,16 +228,10 @@
     // Remove the helper because it isn't needed anymore.
     NewTabAnimationTabHelper::RemoveFromWebState(newWebState);
   }
-  // Since we share the NTP coordinator across web states, the feed type could
-  // be different from default, so we reset it.
   NewTabPageTabHelper* NTPHelper =
       NewTabPageTabHelper::FromWebState(newWebState);
-  if (NTPHelper && NTPHelper->IsActive()) {
+  if (NTPHelper->IsActive()) {
     [_ntpCoordinator start];
-    FeedType defaultFeedType = NTPHelper->DefaultFeedType();
-    if (_ntpCoordinator.selectedFeed != defaultFeedType) {
-      [_ntpCoordinator selectFeedType:defaultFeedType];
-    }
   }
   BOOL inBackground =
       (NTPHelper && NTPHelper->ShouldShowStartSurface()) || !animated;
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
index 897017c9..2bb7c34 100644
--- a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
+++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
@@ -1104,7 +1104,9 @@
 
 // Test that signing in and signing out results in the NTP scrolled to the top
 // and not in some unexpected layout state.
-- (void)testSignInSignOutScrolledToTop {
+// TODO(crbug.com/1433014): Non-stop animation on discover feed after signing
+// out.
+- (void)FLAKY_testSignInSignOutScrolledToTop {
   [[EarlGrey selectElementWithMatcher:chrome_test_util::NTPLogo()]
       assertWithMatcher:grey_sufficientlyVisible()];
   [[EarlGrey selectElementWithMatcher:chrome_test_util::FakeOmnibox()]
diff --git a/ios/chrome/browser/ui/integration_tests/BUILD.gn b/ios/chrome/browser/ui/integration_tests/BUILD.gn
index b5d21e14..5cc26030 100644
--- a/ios/chrome/browser/ui/integration_tests/BUILD.gn
+++ b/ios/chrome/browser/ui/integration_tests/BUILD.gn
@@ -10,6 +10,7 @@
   testonly = true
   sources = [ "pdf_egtest.mm" ]
   deps = [
+    "//ios/chrome/browser/snapshots:features",
     "//ios/chrome/test/earl_grey:eg_test_support+eg2",
     "//ios/testing/earl_grey:eg_test_support+eg2",
     "//net:test_support",
diff --git a/ios/chrome/browser/ui/integration_tests/pdf_egtest.mm b/ios/chrome/browser/ui/integration_tests/pdf_egtest.mm
index aac16e8..3ef28a91 100644
--- a/ios/chrome/browser/ui/integration_tests/pdf_egtest.mm
+++ b/ios/chrome/browser/ui/integration_tests/pdf_egtest.mm
@@ -6,6 +6,9 @@
 #import <XCTest/XCTest.h>
 
 #import "base/test/ios/wait_util.h"
+#import "base/test/scoped_feature_list.h"
+#import "ios/chrome/browser/snapshots/features.h"
+#import "ios/chrome/test/earl_grey/chrome_actions.h"
 #import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
 #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
 #import "ios/chrome/test/earl_grey/chrome_matchers.h"
@@ -17,13 +20,24 @@
 #error "This file requires ARC support."
 #endif
 
+using chrome_test_util::RegularTabGrid;
+using chrome_test_util::ScrollToTop;
+using chrome_test_util::TabGridCellAtIndex;
+
 const char kPDFPath[] = "/complex_document.pdf";
+const char kGreenPDFPath[] = "/green.pdf";
 
 @interface PDFTestCase : ChromeTestCase
 @end
 
 @implementation PDFTestCase
 
+- (AppLaunchConfiguration)appConfigurationForTestCase {
+  AppLaunchConfiguration config;
+  config.features_enabled.push_back(kPDFSnapshot);
+  return config;
+}
+
 // Regression test for crbug/981893. Repro steps: open a PDF in a new
 // tab, switch back and forth betweeen the new tab and the old one by
 // swiping in the toolbar. The regression is a crash.
@@ -106,7 +120,7 @@
 - (void)testPDFIntoTabGridAndWait {
   GREYAssertTrue(self.testServer->Start(), @"Test server failed to start.");
 
-  // Load a page, then a PDF
+  // Load a page, then a PDF.
   [ChromeEarlGrey loadURL:self.testServer->GetURL("/echo")];
   [ChromeEarlGrey loadURL:self.testServer->GetURL(kPDFPath)];
 
@@ -118,4 +132,95 @@
   [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridDoneButton()]
       performAction:grey_tap()];
 }
+
+// Tests the center color of the grid tab showing a PDF. (physical device only)
+- (void)testCenterColorOfPDFTabGrid {
+#if TARGET_IPHONE_SIMULATOR
+  EARL_GREY_TEST_SKIPPED(@"The API to take a snapshot is not working correctly "
+                         @"and it becomes black on simulator.");
+#endif
+
+  GREYAssertTrue(self.testServer->Start(), @"Test server failed to start.");
+
+  // Load a page, then a PDF.
+  [ChromeEarlGrey loadURL:self.testServer->GetURL(kGreenPDFPath)];
+
+  // Open more than 6 pages to scroll down/up in a tab grid.
+  for (int i = 0; i < 10; i++) {
+    [ChromeEarlGreyUI openNewTab];
+    [ChromeEarlGrey loadURL:self.testServer->GetURL("/echo")];
+  }
+
+  // Open a tab grid and then scroll up to make a tab grid cell recycled and
+  // re-created.
+  [ChromeEarlGreyUI openTabGrid];
+  [[EarlGrey selectElementWithMatcher:RegularTabGrid()]
+      performAction:ScrollToTop()];
+
+  // Take a snapshot of the tab grid showing a PDF.
+  EDORemoteVariable<UIImage*>* tabGridSnapshot =
+      [[EDORemoteVariable alloc] init];
+  [[EarlGrey selectElementWithMatcher:TabGridCellAtIndex(0)]
+      performAction:grey_snapshot(tabGridSnapshot)];
+
+  // Get a color of the center position in a tab grid.
+  CGFloat red = 0.0, green = 0.0, blue = 0.0, alpha = 0.0;
+  [self getCenterColor:tabGridSnapshot.object
+                   red:&red
+                 green:&green
+                  blue:&blue
+                 alpha:&alpha];
+
+  // The values may not be exactly 0.0 or 1.0 due to the image compression. The
+  // test allows more flexible values.
+  GREYAssert(
+      red < 0.1,
+      @"A red value of the center color in a tab grid should be close to 0.");
+  GREYAssert(
+      green > 0.9,
+      @"A green value of the center color in a tab grid should be close to 1.");
+  GREYAssert(
+      blue < 0.1,
+      @"A blue value of the center color in a tab grid should be close to 0.");
+  GREYAssert(
+      alpha > 0.9,
+      @"A alpha value of the center color in a tab grid should be close to 1.");
+}
+
+#pragma mark - Helper methods
+
+- (void)getCenterColor:(UIImage*)image
+                   red:(CGFloat*)red
+                 green:(CGFloat*)green
+                  blue:(CGFloat*)blue
+                 alpha:(CGFloat*)alpha {
+  CGImageRef imageRef = [image CGImage];
+
+  NSUInteger width = CGImageGetWidth(imageRef);
+  NSUInteger height = CGImageGetHeight(imageRef);
+  NSUInteger x = width / 2;
+  NSUInteger y = height / 2;
+
+  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+  unsigned char* data =
+      (unsigned char*)calloc(height * width * 4, sizeof(unsigned char));
+  NSUInteger bytesPerPixel = 4;
+  NSUInteger bytesPerRow = bytesPerPixel * width;
+  NSUInteger bitsPerComponent = 8;
+  CGContextRef context =
+      CGBitmapContextCreate(data, width, height, bitsPerComponent, bytesPerRow,
+                            colorSpace, kCGImageAlphaPremultipliedLast);
+  CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
+
+  NSUInteger index = (bytesPerRow * y) + x * bytesPerPixel;
+  *red = ((CGFloat)data[index]) / 255.0f;
+  *green = ((CGFloat)data[index + 1]) / 255.0f;
+  *blue = ((CGFloat)data[index + 2]) / 255.0f;
+  *alpha = ((CGFloat)data[index + 3]) / 255.0f;
+
+  CGColorSpaceRelease(colorSpace);
+  CGContextRelease(context);
+  free(data);
+}
+
 @end
diff --git a/ios/chrome/browser/ui/ntp/BUILD.gn b/ios/chrome/browser/ui/ntp/BUILD.gn
index b3cffe4d..0df1d23e 100644
--- a/ios/chrome/browser/ui/ntp/BUILD.gn
+++ b/ios/chrome/browser/ui/ntp/BUILD.gn
@@ -154,12 +154,17 @@
     "new_tab_page_retention_field_trial.cc",
     "new_tab_page_retention_field_trial.h",
     "new_tab_page_retention_field_trial_constants.h",
+    "synced_segments_field_trial.cc",
+    "synced_segments_field_trial.h",
+    "synced_segments_field_trial_constants.cc",
+    "synced_segments_field_trial_constants.h",
   ]
   public_deps = [
     "//base",
     "//components/variations",
   ]
   deps = [
+    "//components/history/core/browser",
     "//components/ntp_tiles",
     "//components/prefs",
     "//components/version_info:version_info",
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.h b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.h
index 8b527ba4..c4d20b7 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.h
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.h
@@ -11,6 +11,10 @@
 #import "ios/chrome/browser/ui/ntp/logo_animation_controller.h"
 #import "ios/chrome/browser/ui/ntp/new_tab_page_configuring.h"
 
+namespace web {
+class WebState;
+}
+
 @class BubblePresenter;
 @protocol NewTabPageComponentFactoryProtocol;
 @protocol NewTabPageControllerDelegate;
@@ -73,7 +77,7 @@
 - (void)reload;
 
 // Called when the user navigates to the NTP.
-- (void)didNavigateToNTP;
+- (void)didNavigateToNTPInWebState:(web::WebState*)webState;
 
 // Called when the user navigates away from the NTP.
 - (void)didNavigateAwayFromNTP;
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
index 03cbe73..53dfb08 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
@@ -112,16 +112,6 @@
 #error "This file requires ARC support."
 #endif
 
-namespace {
-bool IsNTPActiveForWebState(web::WebState* web_state) {
-  if (!web_state) {
-    return false;
-  }
-  NewTabPageTabHelper* helper = NewTabPageTabHelper::FromWebState(web_state);
-  return helper && helper->IsActive();
-}
-}  // namespace
-
 @interface NewTabPageCoordinator () <AppStateObserver,
                                      BooleanObserver,
                                      ContentSuggestionsHeaderCommands,
@@ -151,9 +141,6 @@
 
   // Observes changes in the DiscoverFeed.
   std::unique_ptr<DiscoverFeedObserverBridge> _discoverFeedObserverBridge;
-
-  // Bridges C++ WebStateListObserver methods to this NewTabPageCoordinator.
-  std::unique_ptr<WebStateListObserverBridge> _webStateListObserver;
 }
 
 // Coordinator for the ContentSuggestions.
@@ -181,13 +168,6 @@
 // Redefined to readwrite.
 @property(nonatomic, assign, readwrite) BOOL visible;
 
-// Whether the view is new tab view is currently presented (possibly in
-// background). Used to report NTP usage metrics.
-@property(nonatomic, assign) BOOL viewPresented;
-
-// Wheter the scene is currently in foreground.
-@property(nonatomic, assign) BOOL sceneInForeground;
-
 // The ViewController displayed by this Coordinator. This is the returned
 // ViewController and will contain the `containedViewController` (Which can
 // change depending on Feed visibility).
@@ -302,16 +282,11 @@
   DCHECK(self.webState);
   DCHECK(NewTabPageTabHelper::FromWebState(self.webState)->IsActive());
 
-  // Start observing WebStateList changes.
-  _webStateListObserver = std::make_unique<WebStateListObserverBridge>(self);
-  self.browser->GetWebStateList()->AddObserver(_webStateListObserver.get());
-
   // Start observing SceneState changes.
   SceneState* sceneState =
       SceneStateBrowserAgent::FromBrowser(self.browser)->GetSceneState();
   [sceneState addObserver:self];
-  self.sceneInForeground =
-      sceneState.activationLevel >= SceneActivationLevelForegroundInactive;
+
   // Configures incognito NTP if user is in incognito mode.
   if (self.browser->GetBrowserState()->IsOffTheRecord()) {
     DCHECK(!self.incognitoViewController);
@@ -320,16 +295,15 @@
     self.incognitoViewController =
         [[IncognitoViewController alloc] initWithUrlLoader:URLLoader];
     self.started = YES;
-    [self NTPDidChangeVisibility:YES];
     return;
   }
 
-  self.selectedFeed =
-      NewTabPageTabHelper::FromWebState(self.webState)->GetNextNTPFeedType();
-
   // NOTE: anything that executes below WILL NOT execute for OffTheRecord
   // browsers!
 
+  self.selectedFeed =
+      NewTabPageTabHelper::FromWebState(self.webState)->GetNextNTPFeedType();
+
   [self initializeServices];
   [self initializeNTPComponents];
   [self startObservers];
@@ -356,15 +330,13 @@
   [self configureNTPViewController];
 
   self.started = YES;
-  [self NTPDidChangeVisibility:YES];
 }
 
 - (void)stop {
-  if (!self.started)
+  if (!self.started) {
     return;
+  }
 
-  self.browser->GetWebStateList()->RemoveObserver(_webStateListObserver.get());
-  _webStateListObserver.reset();
   _webState = nullptr;
 
   SceneState* sceneState =
@@ -374,8 +346,6 @@
   if (self.browser->GetBrowserState()->IsOffTheRecord()) {
     self.incognitoViewController = nil;
     self.started = NO;
-    self.viewPresented = NO;
-    [self updateVisible];
     return;
   }
 
@@ -384,9 +354,6 @@
 
   [sceneState.appState removeObserver:self];
 
-  self.viewPresented = NO;
-  [self updateVisible];
-
   [self.feedManagementCoordinator stop];
   self.feedManagementCoordinator = nil;
   [self.contentSuggestionsCoordinator stop];
@@ -419,6 +386,7 @@
   self.alertCoordinator = nil;
   self.authService = nil;
   self.templateURLService = nil;
+  self.prefService = nil;
 
   [self.NTPMediator shutdown];
   self.NTPMediator = nil;
@@ -499,7 +467,7 @@
 - (void)locationBarDidResignFirstResponder {
   // Do not trigger defocus animation if the user is already navigating away
   // from the NTP.
-  if (self.viewPresented) {
+  if (self.visible) {
     [self.NTPViewController omniboxDidResignFirstResponder];
   }
 }
@@ -535,17 +503,15 @@
   }
 }
 
-- (void)didNavigateToNTP {
-  if (self.started) {
-    self.webState = self.browser->GetWebStateList()->GetActiveWebState();
-    [self NTPDidChangeVisibility:YES];
-  }
+- (void)didNavigateToNTPInWebState:(web::WebState*)webState {
+  CHECK(self.started);
+  self.webState = webState;
+  [self updateNTPIsVisible:YES];
 }
 
 - (void)didNavigateAwayFromNTP {
-  [self NTPDidChangeVisibility:NO];
+  [self updateNTPIsVisible:NO];
   self.webState = nullptr;
-  [self stopIfNeeded];
 }
 
 #pragma mark - Setters
@@ -1373,40 +1339,16 @@
 
 - (void)sceneState:(SceneState*)sceneState
     transitionedToActivationLevel:(SceneActivationLevel)level {
-  self.sceneInForeground = level >= SceneActivationLevelForegroundInactive;
-  [self updateVisible];
-}
-
-#pragma mark - WebStateListObserving methods
-
-- (void)webStateList:(WebStateList*)webStateList
-    didChangeActiveWebState:(web::WebState*)newWebState
-                oldWebState:(web::WebState*)oldWebState
-                    atIndex:(int)atIndex
-                     reason:(ActiveWebStateChangeReason)reason {
-  [self didChangeActiveWebState:newWebState];
+  if (self.webState && !self.visible &&
+      level >= SceneActivationLevelForegroundInactive) {
+    [self updateNTPIsVisible:YES];
+  } else if (self.visible && level < SceneActivationLevelForegroundInactive) {
+    [self updateNTPIsVisible:NO];
+  }
 }
 
 #pragma mark - Private
 
-// Handles a change in the active WebState.
-- (void)didChangeActiveWebState:(web::WebState*)newWebState {
-  if (self.webState == newWebState) {
-    return;
-  }
-
-  if (IsNTPActiveForWebState(self.webState)) {
-    [self NTPDidChangeVisibility:NO];
-  }
-
-  bool active = IsNTPActiveForWebState(newWebState);
-  self.webState = active ? newWebState : nullptr;
-
-  if (active) {
-    [self NTPDidChangeVisibility:YES];
-  }
-}
-
 // Updates the feed visibility or content based on the supervision state
 // of the account defined in `value`.
 - (void)updateFeedWithIsSupervisedUser:(BOOL)value {
@@ -1436,42 +1378,6 @@
   }
 }
 
-// Updates the visible property based on viewPresented and sceneInForeground
-// properties.
-// Sends metrics when NTP becomes invisible.
-- (void)updateVisible {
-  BOOL visible = self.viewPresented && self.sceneInForeground;
-  if (visible == self.visible) {
-    return;
-  }
-  self.visible = visible;
-  if (self.browser->GetBrowserState()->IsOffTheRecord()) {
-    // Do not report metrics on incognito NTP.
-    return;
-  }
-  if (visible) {
-    self.didAppearTime = base::TimeTicks::Now();
-    if ([self isFeedHeaderVisible]) {
-      if ([self.feedExpandedPref value]) {
-        [self.NTPMetricsRecorder
-            recordNTPImpression:IOSNTPImpressionType::kFeedVisible];
-      } else {
-        [self.NTPMetricsRecorder
-            recordNTPImpression:IOSNTPImpressionType::kFeedCollapsed];
-      }
-    } else {
-      [self.NTPMetricsRecorder
-          recordNTPImpression:IOSNTPImpressionType::kFeedDisabled];
-    }
-  } else {
-    if (!self.didAppearTime.is_null()) {
-      [self.NTPMetricsRecorder
-          recordTimeSpentInNTP:base::TimeTicks::Now() - self.didAppearTime];
-      self.didAppearTime = base::TimeTicks();
-    }
-  }
-}
-
 // Updates the NTP to take into account a new feed, or a change in feed
 // visibility.
 - (void)updateNTPForFeed {
@@ -1685,9 +1591,11 @@
 
 // Called when the NTP changes visibility, either when the user navigates to
 // or away from the NTP, or when the active WebState changes.
-- (void)NTPDidChangeVisibility:(BOOL)visible {
-  DCHECK(self.started);
-  DCHECK(self.webState);
+- (void)updateNTPIsVisible:(BOOL)visible {
+  CHECK(visible != self.visible);
+  CHECK(self.webState);
+
+  self.visible = visible;
 
   if (!self.browser->GetBrowserState()->IsOffTheRecord()) {
     [self updateStartForVisibilityChange:visible];
@@ -1711,6 +1619,32 @@
         self.feedMetricsRecorder.feedControlDelegate = self;
         self.feedMetricsRecorder.followDelegate = self;
       }
+      self.didAppearTime = base::TimeTicks::Now();
+      if ([self isFeedHeaderVisible]) {
+        if ([self.feedExpandedPref value]) {
+          [self.NTPMetricsRecorder
+              recordNTPImpression:IOSNTPImpressionType::kFeedVisible];
+        } else {
+          [self.NTPMetricsRecorder
+              recordNTPImpression:IOSNTPImpressionType::kFeedCollapsed];
+        }
+      } else {
+        [self.NTPMetricsRecorder
+            recordNTPImpression:IOSNTPImpressionType::kFeedDisabled];
+      }
+    } else {
+      // Unfocus omnibox, to prevent it from lingering when it should be
+      // dismissed (for example, when navigating away or when changing feed
+      // visibility). Do this after the MVC classes are deallocated so no reset
+      // animations are fired in response to this cancel.
+      id<OmniboxCommands> omniboxCommandHandler = HandlerForProtocol(
+          self.browser->GetCommandDispatcher(), OmniboxCommands);
+      [omniboxCommandHandler cancelOmniboxEdit];
+      if (!self.didAppearTime.is_null()) {
+        [self.NTPMetricsRecorder
+            recordTimeSpentInNTP:base::TimeTicks::Now() - self.didAppearTime];
+        self.didAppearTime = base::TimeTicks();
+      }
     }
     // Check if feed is visible before reporting NTP visibility as the feed
     // needs to be visible in order to use for metrics.
@@ -1720,14 +1654,11 @@
     }
   }
 
-  self.viewPresented = visible;
-  [self updateVisible];
-
   if (!self.browser->GetBrowserState()->IsOffTheRecord() && !visible) {
     // Unfocus omnibox, to prevent it from lingering when it should be
     // dismissed (for example, when navigating away or when changing feed
     // visibility).
-    // Do this after updating `viewPresented` to prevent defocus animation from
+    // Do this after updating `visible` to prevent defocus animation from
     // happening when already navigating away from NTP.
     [self cancelOmniboxEdit];
   }
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator_unittest.mm b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator_unittest.mm
index a4ae15dc..6379147 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator_unittest.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator_unittest.mm
@@ -241,8 +241,8 @@
   ContentSuggestionsCoordinator* mockContentSuggestionsCoordinator =
       coordinator_mock;
 
-  // Test `-start` sets `isStartShowing` to true if NTPTabHelper's
-  // `-ShouldShowStartSurface` is true.
+  // Set next NTP as start surface. Test that starting the NTP and navigating to
+  // it configures the start surface.
   OCMExpect([coordinator_mock alloc]).andReturn(coordinator_mock);
   OCMExpect([coordinator_mock initWithBaseViewController:[OCMArg any]
                                                  browser:browser_.get()])
@@ -250,12 +250,12 @@
   NewTabPageTabHelper::FromWebState(web_state_)->SetShowStartSurface(true);
   OCMExpect([coordinator_mock configureStartSurfaceIfNeeded]);
   [coordinator_ start];
-  EXPECT_OCMOCK_VERIFY(coordinator_mock);
-  [coordinator_ stop];
+  [coordinator_ didNavigateToNTPInWebState:web_state_];
 
-  // Test `-didNavigateToNTP` configures the NTP for Start. `-didNavigateToNTP`
-  // should only be called if the NTPCoordinator is still started (e.g. another
-  // tab has the NTP open).
+  // Test opening a Start surface with another NTP tab opened in the background
+  // (e.g. the NTP coordinator is already started).
+  [coordinator_ didNavigateAwayFromNTP];
+  [coordinator_ stop];
   OCMExpect([coordinator_mock alloc]).andReturn(coordinator_mock);
   OCMExpect([coordinator_mock initWithBaseViewController:[OCMArg any]
                                                  browser:browser_.get()])
@@ -263,10 +263,11 @@
   [coordinator_ start];
   NewTabPageTabHelper::FromWebState(web_state_)->SetShowStartSurface(true);
   OCMExpect([coordinator_mock configureStartSurfaceIfNeeded]);
-  [coordinator_ didNavigateToNTP];
+  [coordinator_ didNavigateToNTPInWebState:web_state_];
   EXPECT_OCMOCK_VERIFY(coordinator_mock);
-  // Test `-didNavigateAwayFromNTP` when currently showing Start resets the
-  // configuration.
+
+  // Test `-didNavigateAwayFromNTPWithinWebState` when currently showing Start
+  // resets the configuration.
   [coordinator_ didNavigateAwayFromNTP];
   EXPECT_FALSE(
       NewTabPageTabHelper::FromWebState(web_state_)->ShouldShowStartSurface());
@@ -274,18 +275,21 @@
 
   // Test `-didChangeActiveWebState:` updates NTP Start state to false if it
   // began as true.
-  NewTabPageTabHelper::FromWebState(web_state_)->SetShowStartSurface(true);
+  // NewTabPageTabHelper::FromWebState(web_state_)->SetShowStartSurface(true);
   OCMExpect([coordinator_mock alloc]).andReturn(coordinator_mock);
   OCMExpect([coordinator_mock initWithBaseViewController:[OCMArg any]
                                                  browser:browser_.get()])
       .andReturn(mockContentSuggestionsCoordinator);
   OCMExpect([coordinator_mock configureStartSurfaceIfNeeded]);
+  NewTabPageTabHelper::FromWebState(web_state_)->SetShowStartSurface(true);
   [coordinator_ start];
+  [coordinator_ didNavigateToNTPInWebState:web_state_];
   EXPECT_OCMOCK_VERIFY(coordinator_mock);
   // Save reference before `web_state_` is set to new active WebState.
   web::WebState* start_web_state = web_state_;
   // Simulate didChangeActiveWebState: callback.
   InsertWebState(CreateWebStateWithURL(GURL("chrome://version")));
+  [coordinator_ didNavigateAwayFromNTP];
   // Moved away from Start surface to a different WebState, Start config for
   // original WebState's TabHelper should be NO.
   EXPECT_FALSE(NewTabPageTabHelper::FromWebState(start_web_state)
@@ -298,6 +302,7 @@
   [[coordinator_mock reject] configureStartSurfaceIfNeeded];
   SetNTPAsCurrentURL();
   [coordinator_ start];
+  [coordinator_ didNavigateToNTPInWebState:web_state_];
   EXPECT_OCMOCK_VERIFY(coordinator_mock);
   [coordinator_ stop];
 }
@@ -312,6 +317,7 @@
   // SetShowStartSurface.
   NewTabPageTabHelper::FromWebState(web_state_)->SetShowStartSurface(true);
   [coordinator_ start];
+  [coordinator_ didNavigateToNTPInWebState:web_state_];
   histogram_tester_->ExpectUniqueSample(
       "IOS.ContentSuggestions.ActionOnStartSurface",
       IOSContentSuggestionsActionType::kFakebox, 0);
@@ -326,6 +332,7 @@
   static_cast<web::FakeWebState*>(web_state_)
       ->OnNavigationStarted(&navigation_context);
   [coordinator_ didNavigateAwayFromNTP];
+  [coordinator_ stopIfNeeded];
   ASSERT_FALSE(coordinator_.started);
   SetNTPAsCurrentURL();
   [coordinator_ start];
@@ -356,6 +363,7 @@
   SetupCommandHandlerMocks();
   NewTabPageTabHelper::FromWebState(web_state_)->SetShowStartSurface(true);
   [coordinator_ start];
+  [coordinator_ didNavigateToNTPInWebState:web_state_];
 
   histogram_tester_->ExpectUniqueSample(
       "IOS.ContentSuggestions.ActionOnStartSurface",
@@ -390,67 +398,75 @@
   [coordinator_ stop];
 }
 
-// Test -didNavigateToNTP to simulate the user navigating back to the NTP, and
-// -didNavigateAwayFromNTP to simulate the user navigating away from the NTP.
-TEST_F(NewTabPageCoordinatorTest, DidNavigate) {
-  CreateCoordinator(/*off_the_record=*/false);
-  SetupCommandHandlerMocks();
-  [coordinator_ start];
-  [coordinator_ sceneState:nil
-      transitionedToActivationLevel:SceneActivationLevelForegroundInactive];
-  EXPECT_TRUE(coordinator_.visible);
-
-  // Create second NTP since `-didNavigateToNTP` should only be called instead
-  // of `-start` when there is another tab showing the NTP.
-  InsertWebState(CreateWebStateWithURL(GURL("chrome://newtab")));
-  // Simulate navigating away from the NTP.
-  web::FakeNavigationContext navigation_context;
-  navigation_context.SetUrl(GURL("chrome://version"));
-  static_cast<web::FakeWebState*>(web_state_)
-      ->OnNavigationStarted(&navigation_context);
-  [coordinator_ didNavigateAwayFromNTP];
-  ASSERT_TRUE(coordinator_.started);
-  EXPECT_EQ(coordinator_.webState, nullptr);
-  EXPECT_FALSE(coordinator_.visible);
-
-  // Simulate navigating back to the NTP.
-  [coordinator_ didNavigateToNTP];
-  EXPECT_EQ(coordinator_.webState, web_state_);
-  EXPECT_TRUE(coordinator_.visible);
-
-  // Remove one of the tabs so that NTPCoordinator will actually stop.
-  browser_->GetWebStateList()->CloseWebStateAt(
-      /*index=*/0, /* close_flags= */ 0);
-  web_state_ = browser_->GetWebStateList()->GetActiveWebState();
-  [coordinator_ stopIfNeeded];
-  ASSERT_FALSE(coordinator_.started);
-}
-
-// Test that NTPCoordinator's DidChangeActiveWebState will change the
-// `webState` property as well as the NTP's visibility appropriately.
-TEST_F(NewTabPageCoordinatorTest, DidChangeActiveWebState) {
+TEST_F(NewTabPageCoordinatorTest, DidNavigateWithinWebState) {
   // Test normal and incognito modes.
   for (bool off_the_record : {false, true}) {
     CreateCoordinator(off_the_record);
     SetupCommandHandlerMocks();
+
+    // Starting the NTP coordinator should not make it visible.
     [coordinator_ start];
-    [coordinator_ sceneState:nil
-        transitionedToActivationLevel:SceneActivationLevelForegroundInactive];
+    EXPECT_TRUE(coordinator_.started);
+    EXPECT_FALSE(coordinator_.visible);
+
+    // Navigate to NTP within the web state and check that NTP is visible.
+    [coordinator_ didNavigateToNTPInWebState:web_state_];
+    EXPECT_TRUE(coordinator_.started);
+    EXPECT_TRUE(coordinator_.visible);
+
+    // Simulate navigating away from the NTP.
+    web::FakeNavigationContext navigation_context;
+    navigation_context.SetUrl(GURL("chrome://version"));
+    static_cast<web::FakeWebState*>(web_state_)
+        ->OnNavigationStarted(&navigation_context);
+    [coordinator_ didNavigateAwayFromNTP];
+
+    // Remove one of the tabs so that NTPCoordinator will actually stop.
+    browser_->GetWebStateList()->CloseWebStateAt(
+        /*index=*/0, /* close_flags= */ 0);
+    [coordinator_ stopIfNeeded];
+    EXPECT_FALSE(coordinator_.started);
+    EXPECT_FALSE(coordinator_.visible);
+  }
+}
+
+TEST_F(NewTabPageCoordinatorTest, DidNavigateBetweenWebStates) {
+  // Test normal and incognito modes.
+  for (bool off_the_record : {false, true}) {
+    CreateCoordinator(off_the_record);
+    SetupCommandHandlerMocks();
+
+    // Starting the NTP coordinator should not make it visible.
+    [coordinator_ start];
+    EXPECT_TRUE(coordinator_.started);
+    EXPECT_FALSE(coordinator_.visible);
+
+    // Open an NTP in a new web state.
+    InsertWebState(CreateWebStateWithURL(GURL("chrome://newtab")));
+    [coordinator_ didNavigateToNTPInWebState:web_state_];
+    EXPECT_TRUE(coordinator_.started);
     EXPECT_TRUE(coordinator_.visible);
 
     // Insert a non-NTP WebState.
     InsertWebState(CreateWebStateWithURL(GURL("chrome://version")));
-    EXPECT_EQ(coordinator_.webState, nullptr);
+    [coordinator_ didNavigateAwayFromNTP];
+    EXPECT_TRUE(coordinator_.started);
     EXPECT_FALSE(coordinator_.visible);
 
-    // Insert an NTP webstate.
-    InsertWebState(CreateWebStateWithURL(GURL("chrome://newtab")));
-    EXPECT_EQ(coordinator_.webState, web_state_);
+    // Close non-NTP web state to get back to NTP web state.
+    browser_->GetWebStateList()->CloseWebStateAt(
+        /*index=*/1, /* close_flags= */ 0);
+    [coordinator_ didNavigateToNTPInWebState:web_state_];
+    EXPECT_TRUE(coordinator_.started);
     EXPECT_TRUE(coordinator_.visible);
 
-    [coordinator_ stop];
-    EXPECT_EQ(coordinator_.webState, nullptr);
-    coordinator_ = nil;
+    // Close all web states.
+    [coordinator_ didNavigateAwayFromNTP];
+    browser_->GetWebStateList()->CloseAllWebStates(
+        WebStateList::CLOSE_NO_FLAGS);
+    [coordinator_ stopIfNeeded];
+    EXPECT_FALSE(coordinator_.visible);
+    EXPECT_FALSE(coordinator_.started);
   }
 }
 
@@ -460,6 +476,7 @@
   CreateCoordinator(/*off_the_record=*/false);
   SetupCommandHandlerMocks();
   [coordinator_ start];
+  [coordinator_ didNavigateToNTPInWebState:web_state_];
 
   ExpectMethodToProxyToVC(@selector(stopScrolling), @selector(stopScrolling));
   ExpectMethodToProxyToVC(@selector(isScrolledToTop),
diff --git a/ios/chrome/browser/ui/ntp/synced_segments_field_trial.cc b/ios/chrome/browser/ui/ntp/synced_segments_field_trial.cc
new file mode 100644
index 0000000..9617faaf
--- /dev/null
+++ b/ios/chrome/browser/ui/ntp/synced_segments_field_trial.cc
@@ -0,0 +1,133 @@
+// 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 "ios/chrome/browser/ui/ntp/synced_segments_field_trial.h"
+
+#include "base/feature_list.h"
+#include "base/metrics/field_trial.h"
+#include "base/metrics/field_trial_params.h"
+#include "components/history/core/browser/features.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/pref_service.h"
+#include "components/version_info/version_info.h"
+#include "ios/chrome/browser/first_run/first_run.h"
+#include "ios/chrome/browser/ui/first_run/ios_first_run_field_trials.h"
+#include "ios/chrome/browser/ui/ntp/synced_segments_field_trial_constants.h"
+#include "ios/chrome/common/channel_info.h"
+
+namespace {
+
+// The placeholder trial version that is stored for a client who has not been
+// enrolled in the experiment.
+const int kPlaceholderTrialVersion = -1;
+
+// Store local state preference with whether the client has participated in
+// `kIOSSyncedSegmentsFieldTrialName` experiment or not.
+const char kTrialPrefName[] = "synced_segments.trial_version";
+
+// The current trial version of
+// `kIOSSyncedSegmentsFieldTrialName`; should be updated when
+// the experiment is modified.
+const int kCurrentTrialVersion = 1;
+
+// Returns a map of the group weights for each arm.
+std::map<variations::VariationID, int> GetGroupWeights() {
+  std::map<variations::VariationID, int> weight_by_id = {
+      {synced_segments_field_trial_constants::kIOSSyncedSegmentsEnabledID, 0},
+      {synced_segments_field_trial_constants::kIOSSyncedSegmentsControlID, 0}};
+
+  return weight_by_id;
+}
+
+}  // namespace
+
+namespace synced_segments_field_trial {
+
+// Creates the trial config, initializes the trial that puts clients into
+// different groups, and returns the version number of the current trial.
+void CreateSyncedSegmentsTrial(
+    std::map<variations::VariationID, int> weight_by_id,
+    const base::FieldTrial::EntropyProvider& low_entropy_provider,
+    base::FeatureList* feature_list) {
+  FirstRunFieldTrialConfig config(
+      synced_segments_field_trial_constants::kIOSSyncedSegmentsFieldTrialName);
+
+  config.AddGroup(
+      synced_segments_field_trial_constants::kIOSSyncedSegmentsControlGroup,
+      synced_segments_field_trial_constants::kIOSSyncedSegmentsControlID,
+      weight_by_id
+          [synced_segments_field_trial_constants::kIOSSyncedSegmentsControlID]);
+
+  config.AddGroup(
+      synced_segments_field_trial_constants::kIOSSyncedSegmentsEnabledGroup,
+      synced_segments_field_trial_constants::kIOSSyncedSegmentsEnabledID,
+      weight_by_id
+          [synced_segments_field_trial_constants::kIOSSyncedSegmentsEnabledID]);
+
+  scoped_refptr<base::FieldTrial> trial = config.CreateOneTimeRandomizedTrial(
+      synced_segments_field_trial_constants::kIOSSyncedSegmentsControlGroup,
+      low_entropy_provider);
+
+  // Finalize the group choice and activates the trial - similar to a variation
+  // config that's marked with `starts_active` true. This is required for
+  // studies that register variation ids, so they don't reveal extra information
+  // beyond the low-entropy source.
+  const std::string& group_name = trial->group_name();
+
+  if (group_name ==
+      synced_segments_field_trial_constants::kIOSSyncedSegmentsEnabledGroup) {
+    feature_list->RegisterFieldTrialOverride(
+        history::kSyncSegmentsData.name,
+        base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial.get());
+  } else if (group_name == synced_segments_field_trial_constants::
+                               kIOSSyncedSegmentsControlGroup) {
+    feature_list->RegisterFieldTrialOverride(
+        history::kSyncSegmentsData.name,
+        base::FeatureList::OVERRIDE_DISABLE_FEATURE, trial.get());
+  }
+}
+
+void RegisterLocalStatePrefs(PrefRegistrySimple* registry) {
+  registry->RegisterIntegerPref(kTrialPrefName, kPlaceholderTrialVersion);
+}
+
+void Create(const base::FieldTrial::EntropyProvider& low_entropy_provider,
+            base::FeatureList* feature_list,
+            PrefService* local_state) {
+  // Don't create the trial if the feature is overridden to avoid having
+  // multiple registered trials for the same feature.
+  if (feature_list->IsFeatureOverridden(synced_segments_field_trial_constants::
+                                            kIOSSyncedSegmentsFieldTrialName)) {
+    return;
+  }
+
+  // If the client is already an existing client by the time this experiment
+  // began running, don't register (e.g. the client is not in a First Run
+  // experience and was never grouped client-side into this study when it went
+  // through First Run). If the user is enrolled in a previous version of the
+  // same experiment, exclude them out of the current version.
+  if (!FirstRun::IsChromeFirstRun() &&
+      local_state->GetInteger(kTrialPrefName) != kCurrentTrialVersion) {
+    return;
+  }
+
+  // Enroll first run clients in the experiment.
+  // If the client is enrolled in the current version of the experiment,
+  // register the trial to keep them in the experiment; they will be placed
+  // in the same group because `low_entropy_provider` is persisted across
+  // launches.
+  CreateSyncedSegmentsTrial(GetGroupWeights(), low_entropy_provider,
+                            feature_list);
+
+  local_state->SetInteger(kTrialPrefName, kCurrentTrialVersion);
+}
+
+void CreateSyncedSegmentsTrialForTesting(
+    std::map<variations::VariationID, int> weights_by_id,
+    const base::FieldTrial::EntropyProvider& low_entropy_provider,
+    base::FeatureList* feature_list) {
+  CreateSyncedSegmentsTrial(weights_by_id, low_entropy_provider, feature_list);
+}
+
+}  // namespace synced_segments_field_trial
diff --git a/ios/chrome/browser/ui/ntp/synced_segments_field_trial.h b/ios/chrome/browser/ui/ntp/synced_segments_field_trial.h
new file mode 100644
index 0000000..eeb0794
--- /dev/null
+++ b/ios/chrome/browser/ui/ntp/synced_segments_field_trial.h
@@ -0,0 +1,35 @@
+// 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 IOS_CHROME_BROWSER_UI_NTP_SYNCED_SEGMENTS_FIELD_TRIAL_H_
+#define IOS_CHROME_BROWSER_UI_NTP_SYNCED_SEGMENTS_FIELD_TRIAL_H_
+
+#include "base/metrics/field_trial.h"
+#include "components/variations/variations_associated_data.h"
+
+class PrefService;
+class PrefRegistrySimple;
+
+namespace synced_segments_field_trial {
+
+// Creates a field trial to control the synced segments experiment.
+//
+// The trial group chosen on first run is persisted to local state prefs.
+void Create(const base::FieldTrial::EntropyProvider& low_entropy_provider,
+            base::FeatureList* feature_list,
+            PrefService* local_state);
+
+// Registers the local state pref used to manage grouping for this field trial.
+void RegisterLocalStatePrefs(PrefRegistrySimple* registry);
+
+// Exposes CreateSyncedSegmentsTrialForTesting() for testing FieldTrial
+// set-up.
+void CreateSyncedSegmentsTrialForTesting(
+    std::map<variations::VariationID, int> weights_by_id,
+    const base::FieldTrial::EntropyProvider& low_entropy_provider,
+    base::FeatureList* feature_list);
+
+}  // namespace synced_segments_field_trial
+
+#endif  // IOS_CHROME_BROWSER_UI_NTP_SYNCED_SEGMENTS_FIELD_TRIAL_H_
diff --git a/ios/chrome/browser/ui/ntp/synced_segments_field_trial_constants.cc b/ios/chrome/browser/ui/ntp/synced_segments_field_trial_constants.cc
new file mode 100644
index 0000000..2540319
--- /dev/null
+++ b/ios/chrome/browser/ui/ntp/synced_segments_field_trial_constants.cc
@@ -0,0 +1,20 @@
+// 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 "ios/chrome/browser/ui/ntp/synced_segments_field_trial_constants.h"
+
+namespace synced_segments_field_trial_constants {
+
+const char kIOSSyncedSegmentsFieldTrialName[] = "IOSSyncedSegments";
+
+const variations::VariationID kIOSSyncedSegmentsEnabledID = 4976469;
+const variations::VariationID kIOSSyncedSegmentsControlID = 4976470;
+
+extern const char kIOSSyncedSegmentsEnabledGroup[] =
+    "IOSSyncedSegmentsEnabled-V1";
+extern const char kIOSSyncedSegmentsControlGroup[] =
+    "IOSSyncedSegmentsControl-V1";
+extern const char kIOSSyncedSegmentsDefaultGroup[] = "Default";
+
+}  // namespace synced_segments_field_trial_constants
diff --git a/ios/chrome/browser/ui/ntp/synced_segments_field_trial_constants.h b/ios/chrome/browser/ui/ntp/synced_segments_field_trial_constants.h
new file mode 100644
index 0000000..3b8a3dd
--- /dev/null
+++ b/ios/chrome/browser/ui/ntp/synced_segments_field_trial_constants.h
@@ -0,0 +1,27 @@
+// 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 IOS_CHROME_BROWSER_UI_NTP_SYNCED_SEGMENTS_FIELD_TRIAL_CONSTANTS_H_
+#define IOS_CHROME_BROWSER_UI_NTP_SYNCED_SEGMENTS_FIELD_TRIAL_CONSTANTS_H_
+
+#include "components/variations/variations_associated_data.h"
+
+namespace synced_segments_field_trial_constants {
+
+// Name of the field trial to configure the synced segments experiment
+// for most visited tiles.
+extern const char kIOSSyncedSegmentsFieldTrialName[];
+
+// Variation IDs for the synced segments experiment arms.
+extern const variations::VariationID kIOSSyncedSegmentsEnabledID;
+extern const variations::VariationID kIOSSyncedSegmentsControlID;
+
+// Group names for the synced segments experiment.
+extern const char kIOSSyncedSegmentsEnabledGroup[];
+extern const char kIOSSyncedSegmentsControlGroup[];
+extern const char kIOSSyncedSegmentsDefaultGroup[];
+
+}  // namespace synced_segments_field_trial_constants
+
+#endif  // IOS_CHROME_BROWSER_UI_NTP_SYNCED_SEGMENTS_FIELD_TRIAL_CONSTANTS_H_
diff --git a/ios/chrome/browser/variations/BUILD.gn b/ios/chrome/browser/variations/BUILD.gn
index 22e60e43..09030ed0 100644
--- a/ios/chrome/browser/variations/BUILD.gn
+++ b/ios/chrome/browser/variations/BUILD.gn
@@ -25,10 +25,12 @@
 source_set("fetcher") {
   configs += [ "//build/config/compiler:enable_arc" ]
   sources = [
+    "ios_chrome_variations_seed_fetcher+testing.h",
     "ios_chrome_variations_seed_fetcher.h",
     "ios_chrome_variations_seed_fetcher.mm",
   ]
   deps = [
+    ":constants",
     ":store",
     ":store_private",
     "//base",
@@ -58,7 +60,11 @@
     ":fetcher",
     ":store",
   ]
-  sources = [ "ios_chrome_variations_seed_store+private.h" ]
+  sources = [ "ios_chrome_variations_seed_store+fetcher.h" ]
+}
+
+source_set("constants") {
+  sources = [ "constants.h" ]
 }
 
 generate_ui_string_overrider("ios_chrome_ui_string_overrider_factory") {
@@ -151,11 +157,9 @@
 source_set("unit_tests") {
   configs += [ "//build/config/compiler:enable_arc" ]
   testonly = true
-  sources = [
-    "ios_chrome_variations_seed_fetcher+testing.h",
-    "ios_chrome_variations_seed_fetcher_unittest.mm",
-  ]
+  sources = [ "ios_chrome_variations_seed_fetcher_unittest.mm" ]
   deps = [
+    ":constants",
     ":fetcher",
     ":store",
     "//base",
diff --git a/ios/chrome/browser/variations/constants.h b/ios/chrome/browser/variations/constants.h
new file mode 100644
index 0000000..21fbc72
--- /dev/null
+++ b/ios/chrome/browser/variations/constants.h
@@ -0,0 +1,22 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_VARIATIONS_CONSTANTS_H_
+#define IOS_CHROME_BROWSER_VARIATIONS_CONSTANTS_H_
+
+// Enum for the seed fetch result histogram. Must stay in sync with
+// `VariationsSeedFetchResult` from enums.xml.
+enum class IOSSeedFetchException : int {
+  // Default value. DO NOT LOG.
+  kNotApplicable = 0,
+  // HTTPS request times out.
+  kHTTPSRequestTimeout = -2,
+  // Variations URL error.
+  kHTTPSRequestBadUrl = -3,
+  // The "IM" header returned from the variations server does not exist or
+  // contains invalid value.
+  kInvalidIMHeader = -5,
+};
+
+#endif  // IOS_CHROME_BROWSER_VARIATIONS_CONSTANTS_H_
diff --git a/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher+testing.h b/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher+testing.h
index 3035db9f..b165861 100644
--- a/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher+testing.h
+++ b/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher+testing.h
@@ -7,10 +7,6 @@
 
 #import <memory>
 
-namespace base {
-class Time;
-}  // namespace base
-
 namespace variations {
 struct SeedResponse;
 }  // namespace variations
@@ -19,13 +15,9 @@
 // IOSChromeVariationsSeedFetcher to be tested.
 @interface IOSChromeVariationsSeedFetcher (Testing)
 
-@property(nonatomic, readonly) NSURL* variationsUrl;
+- (void)doActualFetch;
 
-@property(nonatomic, assign) base::Time startTimeOfOngoingSeedRequest;
-
-- (void)applySwitchesFromArguments:(NSArray<NSString*>*)arguments;
-
-- (void)onSeedRequestCompletedWithData:(NSData*)data
+- (void)seedRequestDidCompleteWithData:(NSData*)data
                               response:(NSHTTPURLResponse*)httpResponse
                                  error:(NSError*)error;
 
diff --git a/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher.h b/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher.h
index 39dbc5d..6202937 100644
--- a/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher.h
+++ b/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher.h
@@ -7,27 +7,14 @@
 
 #import <Foundation/Foundation.h>
 
-// Enum for the seed fetch result histogram. Must stay in sync with
-// `VariationsSeedFetchResult` from enums.xml.
-enum class IOSSeedFetchException : int {
-  // Default value. DO NOT LOG.
-  kNotApplicable = 0,
-  // HTTPS request times out.
-  kHTTPSRequestTimeout = -2,
-  // Variations URL error.
-  kHTTPSRequestBadUrl = -3,
-  // The "IM" header returned from the variations server does not exist or
-  // contains invalid value.
-  kInvalidIMHeader = -5,
-};
-
 // Protocol for variations seed fetcher that reacts to variations seed fetch
 // stages.
 @protocol IOSChromeVariationsSeedFetcherDelegate
 
-// Informs the delegate that the initial seed fetch has successfully completed
-// or failed.
-- (void)didFetchSeedSuccess:(BOOL)succeeded;
+// Informs the delegate that the initial seed fetch has completed.
+// If the value of the `success` parameter is YES, the seed fetch is successful;
+// if NO, the fetch has failed.
+- (void)variationsSeedFetcherDidCompleteFetchWithSuccess:(BOOL)success;
 
 @end
 
@@ -35,10 +22,21 @@
 // components are initialized.
 @interface IOSChromeVariationsSeedFetcher : NSObject
 
-// Delegate object that observes the status of seed fetching.
+// Delegate object that would be informed when the seed fetch completes.
 @property(nonatomic, weak) id<IOSChromeVariationsSeedFetcherDelegate> delegate;
 
-// Starts fetching the initial seed from the variations server.
+// Initializes the seed fetcher using `arguments` as variation switches, and
+// apply them to the seed manager.
+//
+// Note: If the user calls `init`, the fetcher
+// would be initialized with command line arguments.
+- (instancetype)initWithArguments:(NSArray<NSString*>*)arguments
+    NS_DESIGNATED_INITIALIZER;
+
+// Starts fetching the initial seed from the variations server. The `delegate`
+// property would be informed when the fetch completes. If the fetch is
+// successful, the acquired seed would be stored in
+// IOSChromeVariationsSeedStore.
 //
 // Note: the caller is responsible for making sure that a seed fetcher object is
 // only be initiated when there is no valid variations seed available in local
diff --git a/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher.mm b/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher.mm
index ab78bb8e..5f537ab 100644
--- a/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher.mm
+++ b/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher.mm
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #import "ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher.h"
+#import "ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher+testing.h"
 
 #import "base/metrics/histogram_functions.h"
 #import "base/notreached.h"
@@ -14,11 +15,12 @@
 #import "components/variations/variations_switches.h"
 #import "components/variations/variations_url_constants.h"
 #import "components/version_info/version_info.h"
+#import "ios/chrome/browser/variations/constants.h"
 #import "ios/chrome/browser/variations/ios_chrome_variations_seed_store.h"
 #import "ios/chrome/common/channel_info.h"
 #import "net/http/http_status_code.h"
 
-#import "ios/chrome/browser/variations/ios_chrome_variations_seed_store+private.h"
+#import "ios/chrome/browser/variations/ios_chrome_variations_seed_store+fetcher.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -33,39 +35,38 @@
     "IOS.Variations.FirstRun.SeedFetchResult";
 const char kSeedFetchTimeHistogram[] = "IOS.Variations.FirstRun.SeedFetchTime";
 
-// Whether a current request for variations seed is being made; this variable
-// exists that only one instance of the manager updates the global seed at one
-// time.
+// Whether a current request for variations seed is being made.
+//
+// This variable exists so that only one instance of the manager updates the
+// global seed at one time. It is access in the static serial queue
+// "*.first_run_variations_seed_manager" at the start of each task in the queue.
+// If the value is NO, it's set to YES and keep executing the task; otherwise,
+// it aborts the task to make sure the fetch result won't be overriden.
 static BOOL g_seed_fetching_in_progress = NO;
 
 }  // namespace
 
-@interface IOSChromeVariationsSeedFetcher () {
-  // The variations server domain name.
+@implementation IOSChromeVariationsSeedFetcher {
+  // Whether the current binary should fetch Finch seed for experiment purpose.
+  // Accessed on the main thread.
+  BOOL _fetchingEnabled;
+
+  // The variations server domain name. Accessed on the main thread.
   std::string _variationsDomain;
 
-  // The forced channel string retrieved from the command line.
+  // The forced channel string retrieved from the command line. Accessed on the
+  // main thread.
   std::string _forcedChannel;
+
+  // The timestamp when the current seed request starts. This is used for metric
+  // reporting, and will be reset to null value when the request finishes.
+  // Accessed in the static serial queue "*.first_run_variations_seed_manager".
+  base::Time _startTimeOfOngoingSeedRequest;
 }
 
-// Whether the current binary should fetch Finch seed for experiment purpose.
-@property(nonatomic, assign) BOOL fetchingEnabled;
-
-// The URL of the variations server, including query parameters that identifies
-// the request initiator.
-@property(nonatomic, readonly) NSURL* variationsUrl;
-
-// The timestamp when the current seed request starts. This is used for metric
-// reporting, and will be reset to null value when the request finishes.
-@property(nonatomic, assign) base::Time startTimeOfOngoingSeedRequest;
-
-@end
-
-@implementation IOSChromeVariationsSeedFetcher
-
 #pragma mark - Public
 
-- (instancetype)init {
+- (instancetype)initWithArguments:(NSArray<NSString*>*)arguments {
   self = [super init];
   if (self) {
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
@@ -75,12 +76,37 @@
 #endif
     _variationsDomain = variations::kDefaultServerUrl;
     _forcedChannel = std::string();
-    [self applySwitchesFromArguments:[[NSProcessInfo processInfo] arguments]];
+
+    std::string url_switch =
+        "--" + std::string(variations::switches::kVariationsServerURL) + "=";
+    std::string channel_switch =
+        "--" + std::string(variations::switches::kFakeVariationsChannel) + "=";
+    for (NSString* a in arguments) {
+      std::string arg = base::SysNSStringToUTF8(a);
+
+      if (base::StartsWith(arg, url_switch)) {
+        _variationsDomain = arg.substr(url_switch.size());
+        if (!_fetchingEnabled && !_variationsDomain.empty()) {
+          _fetchingEnabled = YES;
+        }
+      } else if (base::StartsWith(arg, channel_switch)) {
+        _forcedChannel = arg.substr(channel_switch.size());
+      }
+    }
   }
   return self;
 }
 
+- (instancetype)init {
+  return [self initWithArguments:[[NSProcessInfo processInfo] arguments]];
+}
+
 - (void)startSeedFetch {
+  if (!_fetchingEnabled) {
+    // Stops executing if seed fetching is disabled.
+    [self notifyDelegateSeedFetchResult:NO];
+    return;
+  }
   // Set up a serial queue to to avoid concurrent read/write to static data.
   static dispatch_once_t onceToken;
   static dispatch_queue_t queue = nil;
@@ -94,15 +120,23 @@
   });
 
   // Adds the task of fetching the seed to the static serial queue, and return
-  // from `startSeedFetch` immediately. Note that the block will retain `self`.
+  // from `doActualFetch` immediately. Note that the block will retain `self`.
   dispatch_async(queue, ^{
-    [self startSeedFetchHelper];
+    if (g_seed_fetching_in_progress) {
+      NOTREACHED() << "SeedFetch started while already in progress";
+      [self notifyDelegateSeedFetchResult:NO];
+    } else {
+      [self doActualFetch];
+    }
   });
 }
 
-#pragma mark - Accessors
+#pragma mark - Private
 
-- (NSURL*)variationsUrl {
+// The URL of the variations server, including query parameters that identifies
+// the request initiator. Accessed in the static serial queue
+// "*.first_run_variations_seed_manager".
+- (NSURL*)variationsURL {
   // Setting "osname", "milestone" and "channel" as parameters. Dogfood
   // experimenting is not supported on Chrome iOS, therefore we do not need the
   // "restrict" parameter.
@@ -119,43 +153,16 @@
       URLWithString:base::SysUTF8ToNSString(_variationsDomain + queryString)];
 }
 
-#pragma mark - Private
-
-// Parse custom values from the command line and apply them to the seed manager.
-- (void)applySwitchesFromArguments:(NSArray<NSString*>*)arguments {
-  std::string url_switch =
-      "--" + std::string(variations::switches::kVariationsServerURL) + "=";
-  std::string channel_switch =
-      "--" + std::string(variations::switches::kFakeVariationsChannel) + "=";
-  for (NSString* a in arguments) {
-    std::string arg = base::SysNSStringToUTF8(a);
-
-    if (base::StartsWith(arg, url_switch)) {
-      _variationsDomain = arg.substr(url_switch.size());
-      if (!self.fetchingEnabled && !_variationsDomain.empty()) {
-        self.fetchingEnabled = YES;
-      }
-    } else if (base::StartsWith(arg, channel_switch)) {
-      _forcedChannel = arg.substr(channel_switch.size());
-    }
-  }
-}
-
 // Helper method for `startSeedFetch` that initiates an HTTPS request to the
-// Finch server in the static serial queue.
-- (void)startSeedFetchHelper {
-  DCHECK(!g_seed_fetching_in_progress)
-      << "SeedFetch started while already in progress";
-
-  // Stops executing if seed fetching is disabled.
-  if (!self.fetchingEnabled) {
-    [self notifyDelegateSeedFetchResult:NO];
-    return;
-  }
-
+// Finch server in the static serial queue
+// "*.first_run_variations_seed_manager".
+//
+// Note that if this method is invoked, the seed would be fetched regardless of
+// `_fetchingEnabled`, so please use with caution.
+- (void)doActualFetch {
   g_seed_fetching_in_progress = YES;
   NSMutableURLRequest* request = [NSMutableURLRequest
-       requestWithURL:self.variationsUrl
+       requestWithURL:[self variationsURL]
           cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
       timeoutInterval:kRequestTimeout.InSecondsF()];
   // Pass only "gzip" as an accepted format. Do not pass delta compression
@@ -166,17 +173,18 @@
       dataTaskWithRequest:request
         completionHandler:^(NSData* data, NSURLResponse* response,
                             NSError* error) {
-          [self onSeedRequestCompletedWithData:data
+          [self seedRequestDidCompleteWithData:data
                                       response:(NSHTTPURLResponse*)response
                                          error:error];
         }];
-  self.startTimeOfOngoingSeedRequest = base::Time::Now();
+  _startTimeOfOngoingSeedRequest = base::Time::Now();
   [task resume];
 }
 
-// Method that generates the seed using the HTTPS response sent back from the
-// Finch server, stores them in the shared seed, and records relevant metrics.
-- (void)onSeedRequestCompletedWithData:(NSData*)data
+// Completion handler of a URL session task. It generates the seed using the
+// HTTPS response sent back from the Finch server, stores them in the shared
+// seed, and records relevant metrics.
+- (void)seedRequestDidCompleteWithData:(NSData*)data
                               response:(NSHTTPURLResponse*)httpResponse
                                  error:(NSError*)error {
   // Normally net::HTTP_NOT_MODIFIED should be considered as a
@@ -185,9 +193,9 @@
   BOOL success = error == nil && httpResponse.statusCode == net::HTTP_OK;
   IOSSeedFetchException exception = IOSSeedFetchException::kNotApplicable;
   if (success) {
-    base::UmaHistogramTimes(
-        kSeedFetchTimeHistogram,
-        base::Time::Now() - self.startTimeOfOngoingSeedRequest);
+    DCHECK(!_startTimeOfOngoingSeedRequest.is_null());
+    base::UmaHistogramTimes(kSeedFetchTimeHistogram,
+                            base::Time::Now() - _startTimeOfOngoingSeedRequest);
     std::unique_ptr<variations::SeedResponse> seed =
         [self seedResponseForHTTPResponse:httpResponse data:data];
     if (seed) {
@@ -206,7 +214,7 @@
              error.code == NSURLErrorCannotFindHost) {
     exception = IOSSeedFetchException::kHTTPSRequestBadUrl;
   }
-  self.startTimeOfOngoingSeedRequest = base::Time();
+  _startTimeOfOngoingSeedRequest = base::Time();
   g_seed_fetching_in_progress = NO;
 
   // Log seed fetch result on UMA and notify delegate.
@@ -219,6 +227,7 @@
 
 // Generates and returns the SeedResponse by parsing the HTTP response returned
 // by the variations server. Returns `nil` if the HTTP response is invalid.
+// Invoked in the completion handler of a URL session task.
 - (std::unique_ptr<variations::SeedResponse>)
     seedResponseForHTTPResponse:(NSHTTPURLResponse*)httpResponse
                            data:(NSData*)data {
@@ -261,7 +270,7 @@
 - (void)notifyDelegateSeedFetchResult:(BOOL)result {
   __weak IOSChromeVariationsSeedFetcher* weakSelf = self;
   dispatch_async(dispatch_get_main_queue(), ^{
-    [weakSelf.delegate didFetchSeedSuccess:result];
+    [weakSelf.delegate variationsSeedFetcherDidCompleteFetchWithSuccess:result];
   });
 }
 
diff --git a/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher_unittest.mm b/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher_unittest.mm
index 7badc13..234c458 100644
--- a/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher_unittest.mm
+++ b/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher_unittest.mm
@@ -13,6 +13,7 @@
 #import "components/variations/variations_switches.h"
 #import "components/variations/variations_url_constants.h"
 #import "components/version_info/version_info.h"
+#import "ios/chrome/browser/variations/constants.h"
 #import "ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher+testing.h"
 #import "ios/chrome/browser/variations/ios_chrome_variations_seed_store.h"
 #import "net/http/http_status_code.h"
@@ -38,7 +39,7 @@
 const char kSeedFetchTimeHistogram[] = "IOS.Variations.FirstRun.SeedFetchTime";
 
 // Fake server url.
-const NSString* testServer = @"https://test.finch.server";
+const NSString* test_server = @"https://test.finch.server";
 
 // Type definition of a block that retrieves the value of an HTTP header from a
 // custom NSDictionary instead of actual NSURLHTTPRequest header.
@@ -48,48 +49,17 @@
 // valueForHTTPHeaderField:].
 MockValueForHTTPHeaderField GetMockMethodWithHeader(
     NSDictionary<NSString*, NSString*>* headers) {
-  void (^outputBlock)(NSInvocation*) = ^(NSInvocation* invocation) {
+  void (^output_block)(NSInvocation*) = ^(NSInvocation* invocation) {
     __weak NSString* arg;
     [invocation getArgument:&arg atIndex:2];
     __weak NSString* value = headers[arg];
     [invocation setReturnValue:&value];
   };
-  return outputBlock;
+  return output_block;
 }
 
 }  // namespace
 
-// A test implementation of IOSChromeVariationsSeedFetcher to be used by
-// test cases. This avoids writing to global variable for the downloaded seed.
-// TODO(crbug.com/1379016): Refactor code so that `fetchingEnabled` could be
-// overridden in a test init method of `IOSChromeVariationsSeedFetcher`.
-@interface TestVariationsSeedFetcher : IOSChromeVariationsSeedFetcher
-
-// Exposure of parent class property.
-@property(nonatomic, assign) BOOL fetchingEnabled;
-
-// Initializer with designated arguments that substitutes for command line args.
-- (instancetype)initWithCommandLineArgsForTesting:
-    (NSArray<NSString*>*)arguments;
-
-@end
-
-@implementation TestVariationsSeedFetcher
-
-- (instancetype)initWithCommandLineArgsForTesting:
-    (NSArray<NSString*>*)arguments {
-  self = [super init];
-  if (self) {
-    self.fetchingEnabled = NO;
-    // This overrides `self.fetchingEnabled` if variations server URL is set in
-    // the argument.
-    [self applySwitchesFromArguments:arguments];
-  }
-  return self;
-}
-
-@end
-
 #pragma mark - Tests
 
 // Tests the IOSChromeVariationsSeedFetcher.
@@ -102,57 +72,6 @@
   }
 };
 
-// Tests that the variations url is correct under different inputs in the
-// command line.
-TEST_F(IOSChromeVariationsSeedFetcherTest, TestVariationsUrl) {
-  NSString* testChannel = @"fake_channel";
-  NSString* testServerArgument =
-      [NSString stringWithFormat:@"--%@=%@",
-                                 base::SysUTF8ToNSString(kVariationsServerURL),
-                                 testServer];
-  NSString* testChannelArgument = [NSString
-      stringWithFormat:@"--%@=%@",
-                       base::SysUTF8ToNSString(kFakeVariationsChannel),
-                       testChannel];
-  // No arguments; use default value.
-  TestVariationsSeedFetcher* fetcherWithDefaultArgs =
-      [[TestVariationsSeedFetcher alloc] initWithCommandLineArgsForTesting:@[]];
-  NSString* expectedUrlPrefix =
-      [NSString stringWithFormat:@"%@?osname=ios&milestone=",
-                                 base::SysUTF8ToNSString(kDefaultServerUrl)];
-  EXPECT_TRUE([fetcherWithDefaultArgs.variationsUrl.absoluteString
-      hasPrefix:expectedUrlPrefix]);
-  // Valid server url and channel arguments.
-  NSString* expectedUrl = [NSString
-      stringWithFormat:@"%@?osname=ios&milestone=%@&channel=%@", testServer,
-                       base::SysUTF8ToNSString(
-                           version_info::GetMajorVersionNumber()),
-                       testChannel];
-  TestVariationsSeedFetcher* fetcherWithValidArgs =
-      [[TestVariationsSeedFetcher alloc] initWithCommandLineArgsForTesting:@[
-        testServerArgument, testChannelArgument
-      ]];
-  EXPECT_NSEQ(fetcherWithValidArgs.variationsUrl.absoluteString, expectedUrl);
-  // Valid server url argument; no channel argument.
-  expectedUrlPrefix = [NSString stringWithFormat:@"%@?osname=ios", testServer];
-  fetcherWithValidArgs = [[TestVariationsSeedFetcher alloc]
-      initWithCommandLineArgsForTesting:@[ testServerArgument ]];
-  EXPECT_TRUE([fetcherWithValidArgs.variationsUrl.absoluteString
-      hasPrefix:expectedUrlPrefix]);
-  EXPECT_FALSE([fetcherWithValidArgs.variationsUrl.absoluteString
-      containsString:testChannel]);
-  // Valid channel argument; no server url argument.
-  expectedUrl =
-      [NSString stringWithFormat:@"%@?osname=ios&milestone=%@&channel=%@",
-                                 base::SysUTF8ToNSString(kDefaultServerUrl),
-                                 base::SysUTF8ToNSString(
-                                     version_info::GetMajorVersionNumber()),
-                                 testChannel];
-  fetcherWithValidArgs = [[TestVariationsSeedFetcher alloc]
-      initWithCommandLineArgsForTesting:@[ testChannelArgument ]];
-  EXPECT_NSEQ(fetcherWithValidArgs.variationsUrl.absoluteString, expectedUrl);
-}
-
 // Tests that the request to the finch server would not be made when seed
 // fetching is not enabled.
 TEST_F(IOSChromeVariationsSeedFetcherTest,
@@ -160,18 +79,18 @@
   // Attach mock delegate.
   id delegate =
       OCMProtocolMock(@protocol(IOSChromeVariationsSeedFetcherDelegate));
-  OCMExpect([delegate didFetchSeedSuccess:NO]);
+  OCMExpect([delegate variationsSeedFetcherDidCompleteFetchWithSuccess:NO]);
   // Start fetching seed from fetcher. Seed fetching is disabled by default in
   // tests.
-  base::HistogramTester histogramTester;
-  TestVariationsSeedFetcher* fetcher =
-      [[TestVariationsSeedFetcher alloc] initWithCommandLineArgsForTesting:@[]];
+  base::HistogramTester histogram_tester;
+  IOSChromeVariationsSeedFetcher* fetcher =
+      [[IOSChromeVariationsSeedFetcher alloc] initWithArguments:@[]];
   fetcher.delegate = delegate;
   [fetcher startSeedFetch];
   base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05));
   EXPECT_OCMOCK_VERIFY(delegate);
-  histogramTester.ExpectTotalCount(kSeedFetchTimeHistogram, 0);
-  histogramTester.ExpectTotalCount(kSeedFetchResultHistogram, 0);
+  histogram_tester.ExpectTotalCount(kSeedFetchTimeHistogram, 0);
+  histogram_tester.ExpectTotalCount(kSeedFetchResultHistogram, 0);
 }
 
 // Tests that the request to the finch server would be made when seed fetching
@@ -179,151 +98,287 @@
 TEST_F(IOSChromeVariationsSeedFetcherTest,
        testThatRequestIsMadeWhenFetchSeedEnabled) {
   // Instantiate mocks.
-  BOOL (^requestMatcher)(NSMutableURLRequest* request) =
+  BOOL (^request_matcher)(NSMutableURLRequest* request) =
       ^BOOL(NSMutableURLRequest* request) {
         // The NSString method `hasPrefix` does not take parameter of type
         // 'const NSString *__strong`.
-        NSString* prefix = [NSString stringWithFormat:@"%@", testServer];
+        NSString* prefix = [NSString stringWithFormat:@"%@", test_server];
         return [request.URL.absoluteString hasPrefix:prefix] &&
                [request.allHTTPHeaderFields[@"A-IM"] isEqualToString:@"gzip"];
       };
-  id mockURLSession = OCMClassMock([NSURLSession class]);
-  OCMStub([mockURLSession sharedSession]).andReturn(mockURLSession);
-  OCMExpect([mockURLSession
-      dataTaskWithRequest:[OCMArg checkWithBlock:requestMatcher]
+  id mock_url_session = OCMClassMock([NSURLSession class]);
+  OCMStub([mock_url_session sharedSession]).andReturn(mock_url_session);
+  OCMExpect([mock_url_session
+      dataTaskWithRequest:[OCMArg checkWithBlock:request_matcher]
         completionHandler:[OCMArg any]]);
   // Start fetching seed from fetcher. Pass a fake value for
   // `kVariationsServerURL` to enable testing.
   NSString* argument =
       [NSString stringWithFormat:@"--%@=%@",
                                  base::SysUTF8ToNSString(kVariationsServerURL),
-                                 testServer];
-  TestVariationsSeedFetcher* fetcher = [[TestVariationsSeedFetcher alloc]
-      initWithCommandLineArgsForTesting:@[ argument ]];
+                                 test_server];
+  IOSChromeVariationsSeedFetcher* fetcher =
+      [[IOSChromeVariationsSeedFetcher alloc] initWithArguments:@[ argument ]];
   [fetcher startSeedFetch];
   base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05));
-  EXPECT_OCMOCK_VERIFY(mockURLSession);
+  EXPECT_OCMOCK_VERIFY(mock_url_session);
 }
 
-// Tests that the seed would not be created when there is a request with the
-// HTTP response, and that the delegate would be notified so.
-TEST_F(IOSChromeVariationsSeedFetcherTest, testHTTPResponseError) {
-  // Instantiate mocks and expectation.
-  id timeoutError = OCMClassMock([NSError class]);
-  OCMStub([timeoutError code]).andReturn(NSURLErrorTimedOut);
-  id responseOk = OCMClassMock([NSHTTPURLResponse class]);
-  OCMStub([responseOk statusCode]).andReturn(net::HTTP_OK);
-  id responseError = OCMClassMock([NSHTTPURLResponse class]);
-  OCMStub([responseError statusCode]).andReturn(net::HTTP_NOT_FOUND);
+// Tests that the default variations url is correct.
+TEST_F(IOSChromeVariationsSeedFetcherTest, TestDefaultVariationsURL) {
+  // Instantiate mocks and expectations.
+  BOOL (^request_matcher)(NSMutableURLRequest* request) =
+      ^BOOL(NSMutableURLRequest* request) {
+        NSString* expected_url_prefix = [NSString
+            stringWithFormat:@"%@?osname=ios&milestone=",
+                             base::SysUTF8ToNSString(kDefaultServerUrl)];
+        return [request.URL.absoluteString hasPrefix:expected_url_prefix];
+      };
+  id mock_url_session = OCMClassMock([NSURLSession class]);
+  OCMStub([mock_url_session sharedSession]).andReturn(mock_url_session);
+  OCMExpect([mock_url_session
+      dataTaskWithRequest:[OCMArg checkWithBlock:request_matcher]
+        completionHandler:[OCMArg any]]);
+  // Fetch and check.
+  IOSChromeVariationsSeedFetcher* fetcher =
+      [[IOSChromeVariationsSeedFetcher alloc] initWithArguments:@[]];
+  [fetcher doActualFetch];
+  base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05));
+  EXPECT_OCMOCK_VERIFY(mock_url_session);
+}
+
+// Tests that the variations url is correct with a fake channel.
+TEST_F(IOSChromeVariationsSeedFetcherTest, TestVariationsURLWithFakeChannel) {
+  NSString* test_channel = @"fake_channel";
+  // Instantiate mocks.
+  BOOL (^request_matcher)(NSMutableURLRequest* request) =
+      ^BOOL(NSMutableURLRequest* request) {
+        NSString* expected_url = [NSString
+            stringWithFormat:@"%@?osname=ios&milestone=%@&channel=%@",
+                             base::SysUTF8ToNSString(kDefaultServerUrl),
+                             base::SysUTF8ToNSString(
+                                 version_info::GetMajorVersionNumber()),
+                             test_channel];
+        return [request.URL.absoluteString isEqualToString:expected_url];
+      };
+  id mock_url_session = OCMClassMock([NSURLSession class]);
+  OCMStub([mock_url_session sharedSession]).andReturn(mock_url_session);
+  OCMExpect([mock_url_session
+      dataTaskWithRequest:[OCMArg checkWithBlock:request_matcher]
+        completionHandler:[OCMArg any]]);
+
+  // Pass a fake value for `kFakeVariationsChannel` to make sure it's
+  // represented in the URL.
+  NSString* test_channel_argument = [NSString
+      stringWithFormat:@"--%@=%@",
+                       base::SysUTF8ToNSString(kFakeVariationsChannel),
+                       test_channel];
+  IOSChromeVariationsSeedFetcher* fetcher =
+      [[IOSChromeVariationsSeedFetcher alloc]
+          initWithArguments:@[ test_channel_argument ]];
+  [fetcher doActualFetch];
+  base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05));
+  EXPECT_OCMOCK_VERIFY(mock_url_session);
+}
+
+// Tests that the variations url is correct with a fake channel and fake
+// server.
+TEST_F(IOSChromeVariationsSeedFetcherTest,
+       TestVariationsURLWithFakeChannelAndFakeServer) {
+  NSString* test_channel = @"fake_channel";
+  // Instantiate mocks.
+  BOOL (^request_matcher)(NSMutableURLRequest* request) = ^BOOL(
+      NSMutableURLRequest* request) {
+    NSString* expected_url = [NSString
+        stringWithFormat:@"%@?osname=ios&milestone=%@&channel=%@", test_server,
+                         base::SysUTF8ToNSString(
+                             version_info::GetMajorVersionNumber()),
+                         test_channel];
+    return [request.URL.absoluteString isEqualToString:expected_url];
+  };
+  id mock_url_session = OCMClassMock([NSURLSession class]);
+  OCMStub([mock_url_session sharedSession]).andReturn(mock_url_session);
+  OCMExpect([mock_url_session
+      dataTaskWithRequest:[OCMArg checkWithBlock:request_matcher]
+        completionHandler:[OCMArg any]]);
+
+  // Pass a fake value for `kFakeVariationsChannel` to make sure it's
+  // represented in the URL.
+  NSString* test_channel_argument = [NSString
+      stringWithFormat:@"--%@=%@",
+                       base::SysUTF8ToNSString(kFakeVariationsChannel),
+                       test_channel];
+  // Pass a fake value for `kVariationsServerURL` to enable testing.
+  NSString* test_server_argument =
+      [NSString stringWithFormat:@"--%@=%@",
+                                 base::SysUTF8ToNSString(kVariationsServerURL),
+                                 test_server];
+
+  IOSChromeVariationsSeedFetcher* fetcher =
+      [[IOSChromeVariationsSeedFetcher alloc]
+          initWithArguments:@[ test_channel_argument, test_server_argument ]];
+  [fetcher doActualFetch];
+  base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05));
+  EXPECT_OCMOCK_VERIFY(mock_url_session);
+}
+
+// Tests that the see won't be created when an HTTP timeout error occurs, and
+// that the delegate would be notified so.
+TEST_F(IOSChromeVariationsSeedFetcherTest, testHTTPTimeoutError) {
+  base::HistogramTester histogram_tester;
+  // Instantiate the mocks
+  id timeout_error = OCMClassMock([NSError class]);
+  OCMStub([timeout_error code]).andReturn(NSURLErrorTimedOut);
+  id response_ok = OCMClassMock([NSHTTPURLResponse class]);
+  OCMStub([response_ok statusCode]).andReturn(net::HTTP_OK);
   id delegate =
       OCMProtocolMock(@protocol(IOSChromeVariationsSeedFetcherDelegate));
-  OCMExpect([delegate didFetchSeedSuccess:NO]);
-  OCMExpect([delegate didFetchSeedSuccess:NO]);
-  // Test if onSeedRequestCompletedWithData:response:error correctly handles
-  // NSError and unexpected response code.
-  TestVariationsSeedFetcher* fetcher =
-      [[TestVariationsSeedFetcher alloc] initWithCommandLineArgsForTesting:@[]];
+  OCMExpect([delegate variationsSeedFetcherDidCompleteFetchWithSuccess:NO]);
+  // Invalidate the NSURLSession so the original request completion handler
+  // would not be executed.
+  id mock_url_session = OCMClassMock([NSURLSession class]);
+  OCMStub([mock_url_session sharedSession]).andReturn(mock_url_session);
+  // Start the test.
+  IOSChromeVariationsSeedFetcher* fetcher =
+      [[IOSChromeVariationsSeedFetcher alloc] initWithArguments:@[]];
   fetcher.delegate = delegate;
-  fetcher.startTimeOfOngoingSeedRequest = base::Time::Now();
-  // Test timeout error.
-  base::HistogramTester histogramTesterTimeoutError;
-  [fetcher onSeedRequestCompletedWithData:nil
-                                 response:responseOk
-                                    error:timeoutError];
+  [fetcher doActualFetch];
+  [fetcher seedRequestDidCompleteWithData:nil
+                                 response:response_ok
+                                    error:timeout_error];
   base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05));
   EXPECT_EQ([IOSChromeVariationsSeedStore popSeed], nil);
-  EXPECT_TRUE(fetcher.startTimeOfOngoingSeedRequest.is_null());
-  histogramTesterTimeoutError.ExpectTotalCount(kSeedFetchTimeHistogram, 0);
-  histogramTesterTimeoutError.ExpectUniqueSample(
+  histogram_tester.ExpectTotalCount(kSeedFetchTimeHistogram, 0);
+  histogram_tester.ExpectUniqueSample(
       kSeedFetchResultHistogram, IOSSeedFetchException::kHTTPSRequestTimeout,
       1);
-  // Test response code error.
-  base::HistogramTester histogramTesterNotFound;
-  fetcher.startTimeOfOngoingSeedRequest = base::Time::Now();
-  [fetcher onSeedRequestCompletedWithData:nil response:responseError error:nil];
-  base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05));
-  EXPECT_EQ([IOSChromeVariationsSeedStore popSeed], nil);
-  EXPECT_TRUE(fetcher.startTimeOfOngoingSeedRequest.is_null());
-  EXPECT_OCMOCK_VERIFY(delegate);
-  histogramTesterNotFound.ExpectTotalCount(kSeedFetchTimeHistogram, 0);
-  histogramTesterNotFound.ExpectUniqueSample(kSeedFetchResultHistogram,
-                                             net::HTTP_NOT_FOUND, 1);
 }
 
-// Tests that the seed creation would be attempted when there is a request with
-// the HTTP response, and that the delegate would be notified if it fails.
+// Tests that the see won't be created when the response code is unexpected, and
+// that the delegate would be notified so.
+TEST_F(IOSChromeVariationsSeedFetcherTest, testHTTPResponseCodeError) {
+  base::HistogramTester histogram_tester;
+  // Instantiate mocks.
+  id response_error = OCMClassMock([NSHTTPURLResponse class]);
+  OCMStub([response_error statusCode]).andReturn(net::HTTP_NOT_FOUND);
+  id delegate =
+      OCMProtocolMock(@protocol(IOSChromeVariationsSeedFetcherDelegate));
+  OCMExpect([delegate variationsSeedFetcherDidCompleteFetchWithSuccess:NO]);
+  // Invalidate the NSURLSession so the original request completion handler
+  // would not be executed.
+  id mock_url_session = OCMClassMock([NSURLSession class]);
+  OCMStub([mock_url_session sharedSession]).andReturn(mock_url_session);
+  // Start the test.
+  IOSChromeVariationsSeedFetcher* fetcher =
+      [[IOSChromeVariationsSeedFetcher alloc] initWithArguments:@[]];
+  fetcher.delegate = delegate;
+  [fetcher doActualFetch];
+  [fetcher seedRequestDidCompleteWithData:nil
+                                 response:response_error
+                                    error:nil];
+  base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05));
+  EXPECT_EQ([IOSChromeVariationsSeedStore popSeed], nil);
+  EXPECT_OCMOCK_VERIFY(delegate);
+  histogram_tester.ExpectTotalCount(kSeedFetchTimeHistogram, 0);
+  histogram_tester.ExpectUniqueSample(kSeedFetchResultHistogram,
+                                      net::HTTP_NOT_FOUND, 1);
+}
+
+// Tests that the seed creation would be attempted when there is a request
+// with the HTTP response, and that the delegate would be notified if it
+// fails.
 TEST_F(IOSChromeVariationsSeedFetcherTest,
        testValidHTTPResponseWithFailingSeedCreation) {
+  base::HistogramTester histogram_tester;
   // Setup.
   id delegate =
       OCMProtocolMock(@protocol(IOSChromeVariationsSeedFetcherDelegate));
-  TestVariationsSeedFetcher* rawfetcher =
-      [[TestVariationsSeedFetcher alloc] initWithCommandLineArgsForTesting:@[]];
-  rawfetcher.delegate = delegate;
-  rawfetcher.startTimeOfOngoingSeedRequest = base::Time::NowFromSystemTime();
+  OCMExpect([delegate variationsSeedFetcherDidCompleteFetchWithSuccess:NO]);
+  IOSChromeVariationsSeedFetcher* fetcher =
+      [[IOSChromeVariationsSeedFetcher alloc] initWithArguments:@[]];
+  fetcher.delegate = delegate;
   id response = OCMClassMock([NSHTTPURLResponse class]);
   OCMStub([response statusCode]).andReturn(net::HTTP_OK);
+  // Invalidate the NSURLSession so the original request completion handler
+  // would not be executed.
+  id mock_url_session = OCMClassMock([NSURLSession class]);
+  OCMStub([mock_url_session sharedSession]).andReturn(mock_url_session);
   // Execute test.
-  id fetcherWithSeed = OCMPartialMock(rawfetcher);
-  OCMStub([fetcherWithSeed seedResponseForHTTPResponse:response data:nil])
-      .andDo(nil);
-  OCMExpect([delegate didFetchSeedSuccess:NO]);
-  base::HistogramTester histogramTester;
-  [fetcherWithSeed onSeedRequestCompletedWithData:nil
-                                         response:response
-                                            error:nil];
+  [fetcher doActualFetch];
+  [fetcher seedRequestDidCompleteWithData:nil response:response error:nil];
   base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05));
-  EXPECT_TRUE([fetcherWithSeed startTimeOfOngoingSeedRequest].is_null());
   EXPECT_EQ([IOSChromeVariationsSeedStore popSeed], nil);
   EXPECT_OCMOCK_VERIFY(delegate);
-  histogramTester.ExpectTotalCount(kSeedFetchTimeHistogram, 1);
-  histogramTester.ExpectUniqueSample(
+  histogram_tester.ExpectTotalCount(kSeedFetchTimeHistogram, 1);
+  histogram_tester.ExpectUniqueSample(
       kSeedFetchResultHistogram, IOSSeedFetchException::kInvalidIMHeader, 1);
 }
 
 // Tests that the seed would not be created when the instance manipulation
-// header format is wrong.
-TEST_F(IOSChromeVariationsSeedFetcherTest, testInvalidInstanceManipulation) {
-  NSString* signature = [NSDate now].description;
-  NSString* country = @"US";
-  NSDictionary<NSString*, NSString*>* headersWithoutIM = @{
-    @"X-Seed-Signature" : signature,
-    @"X-Country" : country,
+// header does not exist.
+TEST_F(IOSChromeVariationsSeedFetcherTest, testNoIMHeader) {
+  // Set up.
+  NSDictionary<NSString*, NSString*>* header = @{
+    @"X-Seed-Signature" : [NSDate now].description,
+    @"X-Country" : @"US",
   };
-  TestVariationsSeedFetcher* fetcher =
-      [[TestVariationsSeedFetcher alloc] initWithCommandLineArgsForTesting:@[]];
-  // No IM.
-  id responseNoIM = OCMClassMock([NSHTTPURLResponse class]);
-  OCMStub([responseNoIM valueForHTTPHeaderField:[OCMArg any]])
-      .andDo(GetMockMethodWithHeader(headersWithoutIM));
+  id response = OCMClassMock([NSHTTPURLResponse class]);
+  OCMStub([response valueForHTTPHeaderField:[OCMArg any]])
+      .andDo(GetMockMethodWithHeader(header));
+  // Execute test.
+  IOSChromeVariationsSeedFetcher* fetcher =
+      [[IOSChromeVariationsSeedFetcher alloc] initWithArguments:@[]];
   std::unique_ptr<variations::SeedResponse> seed =
-      [fetcher seedResponseForHTTPResponse:responseNoIM data:nil];
-  EXPECT_EQ(seed, nullptr);
-  // Incorrect IM.
-  NSMutableDictionary<NSString*, NSString*>* headerWithBadIM =
-      [NSMutableDictionary dictionaryWithDictionary:headersWithoutIM];
-  headerWithBadIM[@"IM"] = @"not_gzip";
-  id responseBadIM = OCMClassMock([NSHTTPURLResponse class]);
-  OCMStub([responseBadIM valueForHTTPHeaderField:[OCMArg any]])
-      .andDo(GetMockMethodWithHeader(headerWithBadIM));
-  seed = [fetcher seedResponseForHTTPResponse:responseBadIM data:nil];
-  EXPECT_EQ(seed, nullptr);
-  // More IM than expected.
-  NSMutableDictionary<NSString*, NSString*>* headerWithTwoIMs =
-      [NSMutableDictionary dictionaryWithDictionary:headersWithoutIM];
-  headerWithTwoIMs[@"IM"] = @"gzip,somethingelse";
-  id responseTwoIMs = OCMClassMock([NSHTTPURLResponse class]);
-  OCMStub([responseTwoIMs valueForHTTPHeaderField:[OCMArg any]])
-      .andDo(GetMockMethodWithHeader(headerWithTwoIMs));
-  seed = [fetcher seedResponseForHTTPResponse:responseTwoIMs data:nil];
+      [fetcher seedResponseForHTTPResponse:response data:nil];
   EXPECT_EQ(seed, nullptr);
 }
 
-// Tests that the seed would be created with property values extracted from the
-// HTTP response with expected header format, and that the delegate would be
-// notified of the successful seed creation.
+// Tests that the seed would not be created when the instance manipulation
+// header is not "gzip".
+TEST_F(IOSChromeVariationsSeedFetcherTest, testBadIMHeader) {
+  // Set up.
+  NSDictionary<NSString*, NSString*>* header = @{
+    @"X-Seed-Signature" : [NSDate now].description,
+    @"X-Country" : @"US",
+    @"IM" : @"not_gzip"
+  };
+  id response = OCMClassMock([NSHTTPURLResponse class]);
+  OCMStub([response valueForHTTPHeaderField:[OCMArg any]])
+      .andDo(GetMockMethodWithHeader(header));
+  // Execute test.
+  IOSChromeVariationsSeedFetcher* fetcher =
+      [[IOSChromeVariationsSeedFetcher alloc] initWithArguments:@[]];
+  std::unique_ptr<variations::SeedResponse> seed =
+      [fetcher seedResponseForHTTPResponse:response data:nil];
+  EXPECT_EQ(seed, nullptr);
+}
+
+// Tests that the seed would not be created when the instance manipulation
+// header has more than one value.
+TEST_F(IOSChromeVariationsSeedFetcherTest, tesMoreThanOneIMHeaders) {
+  // Set up.
+  NSDictionary<NSString*, NSString*>* header = @{
+    @"X-Seed-Signature" : [NSDate now].description,
+    @"X-Country" : @"US",
+    @"IM" : @"gzip,somethingelse"
+  };
+  id response = OCMClassMock([NSHTTPURLResponse class]);
+  OCMStub([response valueForHTTPHeaderField:[OCMArg any]])
+      .andDo(GetMockMethodWithHeader(header));
+  // Execute test.
+  IOSChromeVariationsSeedFetcher* fetcher =
+      [[IOSChromeVariationsSeedFetcher alloc] initWithArguments:@[]];
+  std::unique_ptr<variations::SeedResponse> seed =
+      [fetcher seedResponseForHTTPResponse:response data:nil];
+  EXPECT_EQ(seed, nullptr);
+}
+
+// Tests that the seed would be created with property values extracted from
+// the HTTP response with expected header format, and that the delegate would
+// be notified of the successful seed creation.
 TEST_F(IOSChromeVariationsSeedFetcherTest,
        testValidHTTPResponseWithSuccessfulSeedCreation) {
+  base::HistogramTester histogram_tester;
   NSString* signature = [NSDate now].description;
   NSString* country = @"US";
   NSDictionary<NSString*, NSString*>* headers = @{
@@ -338,26 +393,27 @@
   // Setup.
   id delegate =
       OCMProtocolMock(@protocol(IOSChromeVariationsSeedFetcherDelegate));
-  TestVariationsSeedFetcher* fetcherWithSeed =
-      [[TestVariationsSeedFetcher alloc] initWithCommandLineArgsForTesting:@[]];
-  fetcherWithSeed.delegate = delegate;
-  fetcherWithSeed.startTimeOfOngoingSeedRequest =
-      base::Time::NowFromSystemTime();
+  OCMExpect([delegate variationsSeedFetcherDidCompleteFetchWithSuccess:YES]);
+  IOSChromeVariationsSeedFetcher* fetcher_with_seed =
+      [[IOSChromeVariationsSeedFetcher alloc] initWithArguments:@[]];
+  fetcher_with_seed.delegate = delegate;
+  // Invalidate the NSURLSession so the original request completion handler
+  // would not be executed.
+  id mock_url_session = OCMClassMock([NSURLSession class]);
+  OCMStub([mock_url_session sharedSession]).andReturn(mock_url_session);
   // Execute test.
-  base::HistogramTester histogramTester;
-  OCMExpect([delegate didFetchSeedSuccess:YES]);
-  [fetcherWithSeed onSeedRequestCompletedWithData:nil
-                                         response:response
-                                            error:nil];
+  [fetcher_with_seed doActualFetch];
+  [fetcher_with_seed seedRequestDidCompleteWithData:nil
+                                           response:response
+                                              error:nil];
   base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05));
-  EXPECT_TRUE([fetcherWithSeed startTimeOfOngoingSeedRequest].is_null());
   auto seed = [IOSChromeVariationsSeedStore popSeed];
   ASSERT_NE(seed, nullptr);
   EXPECT_EQ(seed->signature, base::SysNSStringToUTF8(signature));
   EXPECT_EQ(seed->country, base::SysNSStringToUTF8(country));
   EXPECT_EQ(seed->data, "");
   EXPECT_OCMOCK_VERIFY(delegate);
-  histogramTester.ExpectTotalCount(kSeedFetchTimeHistogram, 1);
-  histogramTester.ExpectUniqueSample(kSeedFetchResultHistogram, net::HTTP_OK,
-                                     1);
+  histogram_tester.ExpectTotalCount(kSeedFetchTimeHistogram, 1);
+  histogram_tester.ExpectUniqueSample(kSeedFetchResultHistogram, net::HTTP_OK,
+                                      1);
 }
diff --git a/ios/chrome/browser/variations/ios_chrome_variations_seed_store+private.h b/ios/chrome/browser/variations/ios_chrome_variations_seed_store+fetcher.h
similarity index 90%
rename from ios/chrome/browser/variations/ios_chrome_variations_seed_store+private.h
rename to ios/chrome/browser/variations/ios_chrome_variations_seed_store+fetcher.h
index 010a307c..461f887 100644
--- a/ios/chrome/browser/variations/ios_chrome_variations_seed_store+private.h
+++ b/ios/chrome/browser/variations/ios_chrome_variations_seed_store+fetcher.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 IOS_CHROME_BROWSER_VARIATIONS_IOS_CHROME_VARIATIONS_SEED_STORE_PRIVATE_H_
-#define IOS_CHROME_BROWSER_VARIATIONS_IOS_CHROME_VARIATIONS_SEED_STORE_PRIVATE_H_
+#ifndef IOS_CHROME_BROWSER_VARIATIONS_IOS_CHROME_VARIATIONS_SEED_STORE_FETCHER_H_
+#define IOS_CHROME_BROWSER_VARIATIONS_IOS_CHROME_VARIATIONS_SEED_STORE_FETCHER_H_
 
 // Extraction of seed update method in IOSChromeVariationsSeedStore to
 // be used (and ONLY used) by the fetcher.
@@ -13,4 +13,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_VARIATIONS_IOS_CHROME_VARIATIONS_SEED_STORE_PRIVATE_H_
+#endif  // IOS_CHROME_BROWSER_VARIATIONS_IOS_CHROME_VARIATIONS_SEED_STORE_FETCHER_H_
diff --git a/ios/chrome/browser/variations/ios_chrome_variations_seed_store.mm b/ios/chrome/browser/variations/ios_chrome_variations_seed_store.mm
index aa9f4b07..3bef156 100644
--- a/ios/chrome/browser/variations/ios_chrome_variations_seed_store.mm
+++ b/ios/chrome/browser/variations/ios_chrome_variations_seed_store.mm
@@ -6,7 +6,7 @@
 
 #import "base/no_destructor.h"
 #import "components/variations/seed_response.h"
-#import "ios/chrome/browser/variations/ios_chrome_variations_seed_store+private.h"
+#import "ios/chrome/browser/variations/ios_chrome_variations_seed_store+fetcher.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
diff --git a/ios/components/webui/sync_internals/sync_internals_message_handler.h b/ios/components/webui/sync_internals/sync_internals_message_handler.h
index 945670ca..f28c586 100644
--- a/ios/components/webui/sync_internals/sync_internals_message_handler.h
+++ b/ios/components/webui/sync_internals/sync_internals_message_handler.h
@@ -57,9 +57,6 @@
   // Handler for requestStart message.
   void HandleRequestStart(const base::Value::List& args);
 
-  // Handler for requestStopKeepData message.
-  void HandleRequestStopKeepData(const base::Value::List& args);
-
   // Handler for requestStopClearData message.
   void HandleRequestStopClearData(const base::Value::List& args);
 
diff --git a/ios/components/webui/sync_internals/sync_internals_message_handler.mm b/ios/components/webui/sync_internals/sync_internals_message_handler.mm
index 1f1419553..e9803f73 100644
--- a/ios/components/webui/sync_internals/sync_internals_message_handler.mm
+++ b/ios/components/webui/sync_internals/sync_internals_message_handler.mm
@@ -92,12 +92,6 @@
                           base::Unretained(this)));
 
   web_ui()->RegisterMessageCallback(
-      syncer::sync_ui_util::kRequestStopKeepData,
-      base::BindRepeating(
-          &SyncInternalsMessageHandler::HandleRequestStopKeepData,
-          base::Unretained(this)));
-
-  web_ui()->RegisterMessageCallback(
       syncer::sync_ui_util::kRequestStopClearData,
       base::BindRepeating(
           &SyncInternalsMessageHandler::HandleRequestStopClearData,
@@ -198,18 +192,6 @@
       syncer::SyncFirstSetupCompleteSource::BASIC_FLOW);
 }
 
-void SyncInternalsMessageHandler::HandleRequestStopKeepData(
-    const base::Value::List& args) {
-  DCHECK_EQ(0U, args.size());
-
-  syncer::SyncService* service = GetSyncService();
-  if (!service) {
-    return;
-  }
-
-  service->GetUserSettings()->ClearSyncRequested();
-}
-
 void SyncInternalsMessageHandler::HandleRequestStopClearData(
     const base::Value::List& args) {
   DCHECK_EQ(0U, args.size());
diff --git a/ios/testing/data/http_server_files/green.pdf b/ios/testing/data/http_server_files/green.pdf
new file mode 100644
index 0000000..03b055f
--- /dev/null
+++ b/ios/testing/data/http_server_files/green.pdf
Binary files differ
diff --git a/ios/testing/http_server_bundle_data.filelist b/ios/testing/http_server_bundle_data.filelist
index d833ae0..6509579f 100644
--- a/ios/testing/http_server_bundle_data.filelist
+++ b/ios/testing/http_server_bundle_data.filelist
@@ -16,6 +16,7 @@
 data/http_server_files/download_test_page.html
 data/http_server_files/fullscreen.html
 data/http_server_files/generic.pkpass
+data/http_server_files/green.pdf
 data/http_server_files/history.html
 data/http_server_files/history.js
 data/http_server_files/history_go.html
diff --git a/ios/web_view/internal/webui/web_view_sync_internals_ui.mm b/ios/web_view/internal/webui/web_view_sync_internals_ui.mm
index 734a2fc..b0134b4 100644
--- a/ios/web_view/internal/webui/web_view_sync_internals_ui.mm
+++ b/ios/web_view/internal/webui/web_view_sync_internals_ui.mm
@@ -24,7 +24,6 @@
   // ios/web_view only supports sync in transport mode. Explicitly override sync
   // start and stop messages and perform a no op.
   return message == syncer::sync_ui_util::kRequestStart ||
-         message == syncer::sync_ui_util::kRequestStopKeepData ||
          message == syncer::sync_ui_util::kRequestStopClearData;
 }
 
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn
index b686cae..a5951ea 100644
--- a/media/gpu/BUILD.gn
+++ b/media/gpu/BUILD.gn
@@ -372,7 +372,10 @@
       "vp9_svc_layers.h",
     ]
     configs += [ "//third_party/libvpx:libvpx_config" ]
-    deps += [ "//third_party/libvpx:libvpxrc" ]
+    deps += [
+      "//third_party/libaom:libaomrc",
+      "//third_party/libvpx:libvpxrc",
+    ]
   }
   if (use_libgav1_parser) {
     sources += [
diff --git a/media/gpu/chromeos/BUILD.gn b/media/gpu/chromeos/BUILD.gn
index 165d6ea..53cb5a1 100644
--- a/media/gpu/chromeos/BUILD.gn
+++ b/media/gpu/chromeos/BUILD.gn
@@ -86,8 +86,6 @@
     "vda_video_frame_pool.cc",
     "vda_video_frame_pool.h",
     "video_decoder_pipeline.h",
-    "video_frame_converter.cc",
-    "video_frame_converter.h",
   ]
 
   # TODO(crbug.com/1012587): Merge :fourcc to :common.
diff --git a/media/gpu/chromeos/mailbox_video_frame_converter.cc b/media/gpu/chromeos/mailbox_video_frame_converter.cc
index c633f9b..c9a2d78 100644
--- a/media/gpu/chromeos/mailbox_video_frame_converter.cc
+++ b/media/gpu/chromeos/mailbox_video_frame_converter.cc
@@ -16,7 +16,6 @@
 #include "gpu/command_buffer/service/scheduler.h"
 #include "gpu/ipc/service/gpu_channel.h"
 #include "media/base/format_utils.h"
-#include "media/base/video_frame.h"
 #include "media/base/video_util.h"
 #include "media/gpu/chromeos/platform_video_frame_utils.h"
 #include "media/gpu/macros.h"
@@ -172,7 +171,7 @@
 };
 
 // static
-std::unique_ptr<VideoFrameConverter> MailboxVideoFrameConverter::Create(
+std::unique_ptr<MailboxVideoFrameConverter> MailboxVideoFrameConverter::Create(
     UnwrapFrameCB unwrap_frame_cb,
     scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner,
     GetCommandBufferStubCB get_stub_cb,
@@ -192,7 +191,7 @@
   auto gpu_delegate = std::make_unique<GpuDelegateImpl>(
       gpu_task_runner, std::move(get_gpu_channel_cb));
 
-  return base::WrapUnique<VideoFrameConverter>(new MailboxVideoFrameConverter(
+  return base::WrapUnique(new MailboxVideoFrameConverter(
       std::move(unwrap_frame_cb), std::move(gpu_task_runner),
       std::move(gpu_delegate), enable_unsafe_webgpu));
 }
@@ -212,6 +211,13 @@
   gpu_weak_this_ = gpu_weak_this_factory_.GetWeakPtr();
 }
 
+void MailboxVideoFrameConverter::Initialize(
+    scoped_refptr<base::SequencedTaskRunner> parent_task_runner,
+    OutputCB output_cb) {
+  parent_task_runner_ = std::move(parent_task_runner);
+  output_cb_ = std::move(output_cb);
+}
+
 void MailboxVideoFrameConverter::Destroy() {
   DCHECK(!parent_task_runner_ ||
          parent_task_runner_->RunsTasksInCurrentSequence());
@@ -571,3 +577,12 @@
 }
 
 }  // namespace media
+
+namespace std {
+
+void default_delete<media::MailboxVideoFrameConverter>::operator()(
+    media::MailboxVideoFrameConverter* ptr) const {
+  ptr->Destroy();
+}
+
+}  // namespace std
diff --git a/media/gpu/chromeos/mailbox_video_frame_converter.h b/media/gpu/chromeos/mailbox_video_frame_converter.h
index d330f49..1f1ad92 100644
--- a/media/gpu/chromeos/mailbox_video_frame_converter.h
+++ b/media/gpu/chromeos/mailbox_video_frame_converter.h
@@ -13,7 +13,7 @@
 #include "gpu/command_buffer/common/mailbox.h"
 #include "gpu/ipc/common/surface_handle.h"
 #include "gpu/ipc/service/shared_image_stub.h"
-#include "media/gpu/chromeos/video_frame_converter.h"
+#include "media/base/video_frame.h"
 #include "media/gpu/media_gpu_export.h"
 #include "third_party/skia/include/core/SkAlphaType.h"
 #include "third_party/skia/include/gpu/GrTypes.h"
@@ -34,14 +34,13 @@
 
 namespace media {
 
-class VideoFrame;
-
 // This class is used for converting GpuMemoryBuffer-backed VideoFrames to
 // gpu::Mailbox-backed VideoFrames. See ConvertFrame() for more details. After
 // conversion, the gpu::Mailbox-backed VideoFrame will retain a reference of the
 // VideoFrame passed to ConvertFrame().
-class MEDIA_GPU_EXPORT MailboxVideoFrameConverter : public VideoFrameConverter {
+class MEDIA_GPU_EXPORT MailboxVideoFrameConverter {
  public:
+  using OutputCB = base::RepeatingCallback<void(scoped_refptr<VideoFrame>)>;
   using UnwrapFrameCB =
       base::RepeatingCallback<VideoFrame*(const VideoFrame& wrapped_frame)>;
   using GetCommandBufferStubCB =
@@ -81,7 +80,7 @@
   // |enable_unsafe_webgpu| hints whether to request the creation of
   // SharedImages with SHARED_IMAGE_USAGE_WEBGPU. Returns nullptr if the
   // MailboxVideoFrameConverter can't be created.
-  static std::unique_ptr<VideoFrameConverter> Create(
+  static std::unique_ptr<MailboxVideoFrameConverter> Create(
       UnwrapFrameCB unwrap_frame_cb,
       scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner,
       GetCommandBufferStubCB get_stub_cb,
@@ -91,17 +90,24 @@
   MailboxVideoFrameConverter& operator=(const MailboxVideoFrameConverter&) =
       delete;
 
+  // Initializes the converter. This method must be called before any
+  // ConvertFrame() is called.
+  void Initialize(scoped_refptr<base::SequencedTaskRunner> parent_task_runner,
+                  OutputCB output_cb);
+
   // Enqueues |frame| to be converted to a gpu::Mailbox-backed VideoFrame. If
-  // the |unwrap_frame_cb| supplied in Create() is non-null, |frame| must wrap a
-  // GpuMemoryBuffer-backed VideoFrame that is retrieved via that callback.
+  // the |unwrap_frame_cb| supplied in Create() is non-null, |frame| must wrap
+  // a GpuMemoryBuffer-backed VideoFrame that is retrieved via that callback.
   // Otherwise, |frame| will be used directly and must be a
-  // GpuMemoryBuffer-backed VideoFrame. The generated gpu::Mailbox is kept alive
-  // until the GpuMemoryBuffer-backed VideoFrame is destroyed.
-  void ConvertFrame(scoped_refptr<VideoFrame> frame) override;
-  void AbortPendingFrames() override;
-  bool HasPendingFrames() const override;
+  // GpuMemoryBuffer-backed VideoFrame. The generated gpu::Mailbox is kept
+  // alive until the GpuMemoryBuffer-backed VideoFrame is destroyed. These
+  // methods must be called on |parent_task_runner_|
+  void ConvertFrame(scoped_refptr<VideoFrame> frame);
+  void AbortPendingFrames();
+  bool HasPendingFrames() const;
 
  private:
+  friend struct std::default_delete<MailboxVideoFrameConverter>;
   friend class MailboxVideoFrameConverterTest;
   friend class MailboxVideoFrameConverterWithUnwrappedFramesTest;
 
@@ -117,8 +123,9 @@
       std::unique_ptr<GpuDelegate> gpu_delegate,
       bool enable_unsafe_webgpu);
   // Destructor runs on the GPU main thread.
-  ~MailboxVideoFrameConverter() override;
-  void Destroy() override;
+  ~MailboxVideoFrameConverter();
+
+  void Destroy();
   void DestroyOnGPUThread();
 
   // TODO(crbug.com/998279): replace s/OnGPUThread/OnGPUTaskRunner/.
@@ -206,6 +213,13 @@
 
   const bool enable_unsafe_webgpu_;
 
+  // The working task runner.
+  scoped_refptr<base::SequencedTaskRunner> parent_task_runner_;
+
+  // The callback to return converted frames back to client. This callback will
+  // be called on |parent_task_runner_|.
+  OutputCB output_cb_;
+
   // The weak pointer of this, bound to |parent_task_runner_|.
   // Used at the VideoFrame destruction callback.
   base::WeakPtr<MailboxVideoFrameConverter> parent_weak_this_;
@@ -218,4 +232,15 @@
 };
 
 }  // namespace media
+
+namespace std {
+
+// Specialize std::default_delete to call Destroy().
+template <>
+struct MEDIA_GPU_EXPORT default_delete<media::MailboxVideoFrameConverter> {
+  void operator()(media::MailboxVideoFrameConverter* ptr) const;
+};
+
+}  // namespace std
+
 #endif  // MEDIA_GPU_CHROMEOS_MAILBOX_VIDEO_FRAME_CONVERTER_H_
diff --git a/media/gpu/chromeos/mailbox_video_frame_converter_unittest.cc b/media/gpu/chromeos/mailbox_video_frame_converter_unittest.cc
index 375c74f..95e09246 100644
--- a/media/gpu/chromeos/mailbox_video_frame_converter_unittest.cc
+++ b/media/gpu/chromeos/mailbox_video_frame_converter_unittest.cc
@@ -124,7 +124,7 @@
   std::vector<std::unique_ptr<StrictMock<base::MockOnceCallback<void()>>>>
       mock_frame_destruction_cbs_;
 
-  std::unique_ptr<VideoFrameConverter> converter_;
+  std::unique_ptr<MailboxVideoFrameConverter> converter_;
 };
 
 class MailboxVideoFrameConverterWithUnwrappedFramesTest
@@ -133,8 +133,7 @@
   MailboxVideoFrameConverterWithUnwrappedFramesTest() {
     auto mock_gpu_delegate = std::make_unique<StrictMock<MockGpuDelegate>>();
     mock_gpu_delegate_ = mock_gpu_delegate.get();
-    converter_ = base::WrapUnique<
-        VideoFrameConverter>(new MailboxVideoFrameConverter(
+    converter_ = base::WrapUnique(new MailboxVideoFrameConverter(
         /*unwrap_frame_cb=*/base::NullCallback(),
         /*gpu_task_runner=*/base::ThreadPool::CreateSingleThreadTaskRunner({}),
         std::move(mock_gpu_delegate),
diff --git a/media/gpu/chromeos/video_decoder_pipeline.cc b/media/gpu/chromeos/video_decoder_pipeline.cc
index 6e66f2f9a..43b851c 100644
--- a/media/gpu/chromeos/video_decoder_pipeline.cc
+++ b/media/gpu/chromeos/video_decoder_pipeline.cc
@@ -194,7 +194,7 @@
     const gpu::GpuDriverBugWorkarounds& workarounds,
     scoped_refptr<base::SequencedTaskRunner> client_task_runner,
     std::unique_ptr<DmabufVideoFramePool> frame_pool,
-    std::unique_ptr<VideoFrameConverter> frame_converter,
+    std::unique_ptr<MailboxVideoFrameConverter> frame_converter,
     std::vector<Fourcc> renderable_fourccs,
     std::unique_ptr<MediaLog> media_log,
     mojo::PendingRemote<stable::mojom::StableVideoDecoder> oop_video_decoder) {
@@ -307,7 +307,7 @@
     const gpu::GpuDriverBugWorkarounds& gpu_workarounds,
     scoped_refptr<base::SequencedTaskRunner> client_task_runner,
     std::unique_ptr<DmabufVideoFramePool> frame_pool,
-    std::unique_ptr<VideoFrameConverter> frame_converter,
+    std::unique_ptr<MailboxVideoFrameConverter> frame_converter,
     std::vector<Fourcc> renderable_fourccs,
     std::unique_ptr<MediaLog> media_log,
     CreateDecoderFunctionCB create_decoder_function_cb,
diff --git a/media/gpu/chromeos/video_decoder_pipeline.h b/media/gpu/chromeos/video_decoder_pipeline.h
index 28216ea3..35d31480 100644
--- a/media/gpu/chromeos/video_decoder_pipeline.h
+++ b/media/gpu/chromeos/video_decoder_pipeline.h
@@ -22,7 +22,7 @@
 #include "media/gpu/chromeos/chromeos_status.h"
 #include "media/gpu/chromeos/fourcc.h"
 #include "media/gpu/chromeos/image_processor_with_pool.h"
-#include "media/gpu/chromeos/video_frame_converter.h"
+#include "media/gpu/chromeos/mailbox_video_frame_converter.h"
 #include "media/gpu/media_gpu_export.h"
 #include "media/mojo/mojom/stable/stable_video_decoder.mojom.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -155,7 +155,7 @@
       const gpu::GpuDriverBugWorkarounds& workarounds,
       scoped_refptr<base::SequencedTaskRunner> client_task_runner,
       std::unique_ptr<DmabufVideoFramePool> frame_pool,
-      std::unique_ptr<VideoFrameConverter> frame_converter,
+      std::unique_ptr<MailboxVideoFrameConverter> frame_converter,
       std::vector<Fourcc> renderable_fourccs,
       std::unique_ptr<MediaLog> media_log,
       mojo::PendingRemote<stable::mojom::StableVideoDecoder> oop_video_decoder);
@@ -228,7 +228,7 @@
       const gpu::GpuDriverBugWorkarounds& workarounds,
       scoped_refptr<base::SequencedTaskRunner> client_task_runner,
       std::unique_ptr<DmabufVideoFramePool> frame_pool,
-      std::unique_ptr<VideoFrameConverter> frame_converter,
+      std::unique_ptr<MailboxVideoFrameConverter> frame_converter,
       std::vector<Fourcc> renderable_fourccs,
       std::unique_ptr<MediaLog> media_log,
       CreateDecoderFunctionCB create_decoder_function_cb,
@@ -327,7 +327,7 @@
 
   // The frame converter passed from the client, otherwise used and destroyed on
   // |decoder_task_runner_|.
-  std::unique_ptr<VideoFrameConverter> frame_converter_
+  std::unique_ptr<MailboxVideoFrameConverter> frame_converter_
       GUARDED_BY_CONTEXT(decoder_sequence_checker_);
 
   // The set of output formats allowed to be used in order of preference.
diff --git a/media/gpu/chromeos/video_frame_converter.cc b/media/gpu/chromeos/video_frame_converter.cc
deleted file mode 100644
index c2fee61..0000000
--- a/media/gpu/chromeos/video_frame_converter.cc
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2019 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/gpu/chromeos/video_frame_converter.h"
-#include "base/task/sequenced_task_runner.h"
-
-namespace media {
-
-VideoFrameConverter::VideoFrameConverter() = default;
-
-VideoFrameConverter::~VideoFrameConverter() = default;
-
-void VideoFrameConverter::Destroy() {
-  delete this;
-}
-
-void VideoFrameConverter::Initialize(
-    scoped_refptr<base::SequencedTaskRunner> parent_task_runner,
-    OutputCB output_cb) {
-  parent_task_runner_ = std::move(parent_task_runner);
-  output_cb_ = std::move(output_cb);
-}
-
-void VideoFrameConverter::ConvertFrame(scoped_refptr<VideoFrame> frame) {
-  DCHECK(parent_task_runner_->RunsTasksInCurrentSequence());
-  DCHECK(output_cb_);
-
-  output_cb_.Run(std::move(frame));
-}
-
-void VideoFrameConverter::AbortPendingFrames() {}
-
-bool VideoFrameConverter::HasPendingFrames() const {
-  return false;
-}
-
-}  // namespace media
-
-namespace std {
-
-void default_delete<media::VideoFrameConverter>::operator()(
-    media::VideoFrameConverter* ptr) const {
-  ptr->Destroy();
-}
-
-}  // namespace std
diff --git a/media/gpu/chromeos/video_frame_converter.h b/media/gpu/chromeos/video_frame_converter.h
deleted file mode 100644
index fed2894..0000000
--- a/media/gpu/chromeos/video_frame_converter.h
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2019 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_GPU_CHROMEOS_VIDEO_FRAME_CONVERTER_H_
-#define MEDIA_GPU_CHROMEOS_VIDEO_FRAME_CONVERTER_H_
-
-#include <memory>
-
-#include "base/functional/callback_forward.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_refptr.h"
-#include "base/task/sequenced_task_runner.h"
-#include "media/base/video_frame.h"
-#include "media/gpu/media_gpu_export.h"
-
-namespace media {
-
-// Video decoders make use of a video frame pool to allocate output frames,
-// which are sent to the client after decoding. However, the storage type of the
-// allocated frame can be different from what the client expects. This class
-// can be used to convert the type of output video frame in this case.
-class MEDIA_GPU_EXPORT VideoFrameConverter {
- public:
-  using OutputCB = base::RepeatingCallback<void(scoped_refptr<VideoFrame>)>;
-
-  VideoFrameConverter();
-
-  VideoFrameConverter(const VideoFrameConverter&) = delete;
-  VideoFrameConverter& operator=(const VideoFrameConverter&) = delete;
-
-  // Initialize the converter. This method must be called before any
-  // ConvertFrame() is called.
-  void Initialize(scoped_refptr<base::SequencedTaskRunner> parent_task_runner,
-                  OutputCB output_cb);
-
-  // Convert the frame and return the converted frame to the client by
-  // |output_cb_|. This method must be called on |parent_task_runner_|.
-  // The default implementation calls |output_cb_| with |frame| as-is.
-  virtual void ConvertFrame(scoped_refptr<VideoFrame> frame);
-
-  // Abort all pending frames. |output_cb_| should not be called for the input
-  // frames passed before calling AbortPendingFrames(). This method must be
-  // called on |parent_task_runner_|.
-  virtual void AbortPendingFrames();
-
-  // Return true if there is any pending frame. This method must be called on
-  // |parent_task_runner_|.
-  virtual bool HasPendingFrames() const;
-
- protected:
-  // Deletion is only allowed via Destroy().
-  virtual ~VideoFrameConverter();
-
-  // The working task runner.
-  scoped_refptr<base::SequencedTaskRunner> parent_task_runner_;
-
-  // The callback to return converted frames back to client. This callback will
-  // be called on |parent_task_runner_|.
-  OutputCB output_cb_;
-
- private:
-  friend struct std::default_delete<VideoFrameConverter>;
-  // Called by std::default_delete.
-  virtual void Destroy();
-};
-
-}  // namespace media
-
-namespace std {
-
-// Specialize std::default_delete to call Destroy().
-template <>
-struct MEDIA_GPU_EXPORT default_delete<media::VideoFrameConverter> {
-  void operator()(media::VideoFrameConverter* ptr) const;
-};
-
-}  // namespace std
-
-#endif  // MEDIA_GPU_CHROMEOS_VIDEO_FRAME_CONVERTER_H_
diff --git a/media/gpu/vaapi/BUILD.gn b/media/gpu/vaapi/BUILD.gn
index 6881291..e65f9948 100644
--- a/media/gpu/vaapi/BUILD.gn
+++ b/media/gpu/vaapi/BUILD.gn
@@ -107,6 +107,7 @@
     "//media/gpu/chromeos:common",
     "//media/parsers",
     "//mojo/public/cpp/bindings",
+    "//third_party/libaom:libaomrc",
     "//third_party/libvpx:libvpxrc",
     "//third_party/libyuv",
     "//ui/gfx",
diff --git a/media/gpu/vaapi/av1_vaapi_video_encoder_delegate.cc b/media/gpu/vaapi/av1_vaapi_video_encoder_delegate.cc
index bac8e57..702a9db 100644
--- a/media/gpu/vaapi/av1_vaapi_video_encoder_delegate.cc
+++ b/media/gpu/vaapi/av1_vaapi_video_encoder_delegate.cc
@@ -8,8 +8,10 @@
 
 #include "base/bits.h"
 #include "base/logging.h"
+#include "media/gpu/macros.h"
 #include "media/gpu/vaapi/vaapi_common.h"
 #include "media/gpu/vaapi/vaapi_wrapper.h"
+#include "third_party/libaom/source/libaom/av1/ratectrl_rtc.h"
 #include "third_party/libgav1/src/src/utils/constants.h"
 
 namespace media {
@@ -17,11 +19,16 @@
 
 // Values from
 // third_party/webrtc/modules/video_coding/codecs/av1/libaom_av1_encoder.cc
-// TODO(b/267521747): We might need to adjust these when we actually implement
-// rate control.
 constexpr int kKFPeriod = 3000;
+// Quantization parameters for AV1. Between 0 and 255.
+constexpr int kMinQIndex = 145;
+constexpr int kMaxQIndex = 205;
+
+// From //third_party/webrtc/media/engine/webrtc_video_engine.h
+// These are also quantization parameters, but these are in different units than
+// above. These are used in AV1 rate control and are between 0 and 63.
 constexpr int kMinQP = 10;
-constexpr int kMaxQP = 205;
+constexpr int kMaxQP = 56;
 
 // This needs to be 64, not 16, because of superblocks.
 // TODO: Look into whether or not we can reduce alignment to 16.
@@ -264,8 +271,6 @@
 bool AV1VaapiVideoEncoderDelegate::Initialize(
     const VideoEncodeAccelerator::Config& config,
     const VaapiVideoEncoderDelegate::Config& ave_config) {
-  // TODO(b/267521747): Implement rate control
-
   if (config.output_profile != VideoCodecProfile::AV1PROFILE_PROFILE_MAIN) {
     LOG(ERROR) << "Invalid profile: " << GetProfileName(config.output_profile);
     return false;
@@ -283,6 +288,8 @@
 
   current_params_.framerate = config.initial_framerate.value_or(
       VideoEncodeAccelerator::kDefaultFramerate);
+  current_params_.bitrate_allocation.SetBitrate(0, 0,
+                                                config.bitrate.target_bps());
 
   level_idx_ = ComputeLevel(coded_size_, current_params_.framerate);
   if (level_idx_ < 0) {
@@ -292,7 +299,8 @@
 
   frame_num_ = current_params_.intra_period;
 
-  return true;
+  return UpdateRates(current_params_.bitrate_allocation,
+                     current_params_.framerate);
 }
 
 AV1VaapiVideoEncoderDelegate::~AV1VaapiVideoEncoderDelegate() = default;
@@ -302,8 +310,42 @@
     uint32_t framerate) {
   // TODO(b/267521747): Implement rate control
 
+  current_params_.bitrate_allocation = bitrate_allocation;
   current_params_.framerate = framerate;
 
+  aom::AV1RateControlRtcConfig rc_config;
+  rc_config.width = coded_size_.width();
+  rc_config.height = coded_size_.height();
+  // third_party/webrtc/modules/video_coding/codecs/av1/libaom_av1_encoder.cc
+  rc_config.max_quantizer = kMaxQP;
+  rc_config.min_quantizer = kMinQP;
+  rc_config.target_bandwidth =
+      current_params_.bitrate_allocation.GetSumBps() / 1000;
+  rc_config.buf_initial_sz = 600;
+  rc_config.buf_optimal_sz = 600;
+  rc_config.buf_sz = 1000;
+  rc_config.undershoot_pct = 50;
+  rc_config.overshoot_pct = 50;
+  rc_config.max_intra_bitrate_pct = 300;
+  rc_config.max_inter_bitrate_pct = 0;
+  rc_config.framerate = current_params_.framerate;
+  rc_config.layer_target_bitrate[0] =
+      current_params_.bitrate_allocation.GetSumBps() / 1000;
+  rc_config.ts_rate_decimator[0] = 1;
+  rc_config.aq_mode = 0;
+  rc_config.ss_number_layers = 1;
+  rc_config.ts_number_layers = 1;
+  rc_config.max_quantizers[0] = kMaxQP;
+  rc_config.min_quantizers[0] = kMinQP;
+  rc_config.scaling_factor_num[0] = 1;
+  rc_config.scaling_factor_den[0] = 1;
+
+  if (!rate_ctrl_) {
+    rate_ctrl_ = AV1RateControl::Create(rc_config);
+    return !!rate_ctrl_;
+  }
+
+  rate_ctrl_->UpdateRateControl(rc_config);
   return true;
 }
 
@@ -375,7 +417,14 @@
 
 void AV1VaapiVideoEncoderDelegate::BitrateControlUpdate(
     const BitstreamBufferMetadata& metadata) {
-  // TODO(b:267521747): Implement proper bitrate control.
+  DVLOGF(4) << "encoded chunk size=" << metadata.payload_size_bytes;
+
+  aom::AV1FrameParamsRTC frame_params;
+  frame_params.frame_type =
+      metadata.key_frame ? aom::kKeyFrame : aom::kInterFrame;
+  frame_params.spatial_layer_id = 0;
+  frame_params.temporal_layer_id = 0;
+  rate_ctrl_->PostEncodeUpdate(metadata.payload_size_bytes, frame_params);
 }
 
 // See section 5.6 of the AV1 specification.
@@ -648,16 +697,23 @@
   pic_param.mode_deltas[0] = 0;
   pic_param.mode_deltas[0] = 0;
 
-  pic_param.base_qindex = 128;  // TODO(b/267521747): replace this fake value
-                                // with real rate control logic.
+  aom::AV1FrameParamsRTC frame_params;
+  frame_params.frame_type = is_keyframe ? aom::kKeyFrame : aom::kInterFrame;
+  frame_params.spatial_layer_id = 0;
+  frame_params.temporal_layer_id = 0;
+  // This method name is a misnomer, GetQP() actually returns the QP in QIndex
+  // form.
+  pic_param.base_qindex = rate_ctrl_->ComputeQP(frame_params);
+  DVLOGF(4) << "qp=" << pic_param.base_qindex
+            << (is_keyframe ? " (keyframe)" : "");
   pic_param.y_dc_delta_q = 0;
   pic_param.u_dc_delta_q = 0;
   pic_param.u_ac_delta_q = 0;
   pic_param.v_dc_delta_q = 0;
   pic_param.v_ac_delta_q = 0;
 
-  pic_param.min_base_qindex = kMinQP;
-  pic_param.max_base_qindex = kMaxQP;
+  pic_param.min_base_qindex = kMinQIndex;
+  pic_param.max_base_qindex = kMaxQIndex;
 
   pic_param.qmatrix_flags.bits.using_qmatrix = 0;
   pic_param.qmatrix_flags.bits.qm_y = 0;
diff --git a/media/gpu/vaapi/av1_vaapi_video_encoder_delegate.h b/media/gpu/vaapi/av1_vaapi_video_encoder_delegate.h
index 51c463f7..5469b68 100644
--- a/media/gpu/vaapi/av1_vaapi_video_encoder_delegate.h
+++ b/media/gpu/vaapi/av1_vaapi_video_encoder_delegate.h
@@ -10,6 +10,13 @@
 #include "media/base/video_bitrate_allocation.h"
 #include "media/gpu/av1_picture.h"
 #include "media/gpu/vaapi/vaapi_video_encoder_delegate.h"
+#include "media/gpu/video_rate_control.h"
+
+namespace aom {
+struct AV1RateControlRtcConfig;
+struct AV1FrameParamsRTC;
+class AV1RateControlRTC;
+}  // namespace aom
 
 namespace media {
 
@@ -64,6 +71,10 @@
   std::vector<gfx::Size> GetSVCLayerResolutions() override;
 
  private:
+  using AV1RateControl = VideoRateControl<aom::AV1RateControlRtcConfig,
+                                          aom::AV1RateControlRTC,
+                                          aom::AV1FrameParamsRTC>;
+
   BitstreamBufferMetadata GetMetadata(const EncodeJob& encode_job,
                                       size_t payload_size) override;
   bool PrepareEncodeJob(EncodeJob& encode_job) override;
@@ -97,6 +108,7 @@
   // reference frames, not just the most recent.
   scoped_refptr<AV1Picture> last_frame_ = nullptr;
   VAEncSequenceParameterBufferAV1 seq_param_;
+  std::unique_ptr<AV1RateControl> rate_ctrl_;
 };
 
 }  // namespace media
diff --git a/media/gpu/video_rate_control.cc b/media/gpu/video_rate_control.cc
index 1e68501..6d884d8 100644
--- a/media/gpu/video_rate_control.cc
+++ b/media/gpu/video_rate_control.cc
@@ -4,6 +4,7 @@
 
 #include "media/gpu/video_rate_control.h"
 
+#include "third_party/libaom/source/libaom/av1/ratectrl_rtc.h"
 #include "third_party/libvpx/source/libvpx/vp8/vp8_ratectrl_rtc.h"
 #include "third_party/libvpx/source/libvpx/vp9/ratectrl_rtc.h"
 
@@ -36,4 +37,13 @@
   impl_->PostEncodeUpdate(encoded_frame_size);
 }
 
+template <>
+void VideoRateControl<aom::AV1RateControlRtcConfig,
+                      aom::AV1RateControlRTC,
+                      aom::AV1FrameParamsRTC>::
+    PostEncodeUpdate(uint64_t encoded_frame_size,
+                     const aom::AV1FrameParamsRTC& frame_params) {
+  impl_->PostEncodeUpdate(encoded_frame_size);
+}
+
 }  // namespace media
diff --git a/media/test/BUILD.gn b/media/test/BUILD.gn
index 46438ff3..c672ba43 100644
--- a/media/test/BUILD.gn
+++ b/media/test/BUILD.gn
@@ -55,7 +55,10 @@
 source_set("pipeline_integration_tests") {
   testonly = true
 
-  if (media_use_ffmpeg) {
+  # Even if FFmpeg is enabled on Android we don't want these.
+  # TODO(watk): Refactor tests that could be made to run on Android. See
+  # http://crbug.com/570762
+  if (media_use_ffmpeg && !is_android) {
     sources = [ "pipeline_integration_test.cc" ]
 
     deps = [
@@ -67,9 +70,13 @@
       "//media/mojo/clients",
 
       # Needed for the opus_config
-      "//testing/gmock",
       "//third_party/opus",
       "//url",
+
+      # TODO(dalecurtis): Required since the gmock header is included in the
+      # header for pipeline_integration_test_base.h.  This should be moved
+      #  into the .cc file to avoid the extra dependency here.
+      "//testing/gmock",
     ]
   }
 }
@@ -83,9 +90,13 @@
     deps = [
       ":pipeline_integration_test_base",
       "//media:test_support",
-      "//testing/gmock",
       "//testing/gtest",
       "//testing/perf",
+
+      # TODO(dalecurtis): Required since the gmock header is included in the
+      # header for pipeline_integration_test_base.h.  This should be moved into
+      # the .cc file to avoid the extra dependency here.
+      "//testing/gmock",
     ]
   }
 }
@@ -160,7 +171,14 @@
       "//base",
       "//base/test:test_support",
       "//media",
+
+      # TODO(dalecurtis): Required since the gmock header is included in the
+      # header for pipeline_integration_test_base.h.  This should be
+      # moved into the .cc file to avoid the extra dependency here.
       "//testing/gmock",
+
+      # TODO(https://crbug.com/1039559): Required for inclusion of
+      # gtest-internal-inl.h.
       "//testing/gtest",
       "//ui/gfx:test_support",
     ]
diff --git a/media/test/pipeline_integration_test.cc b/media/test/pipeline_integration_test.cc
index 2049b32..2c85178 100644
--- a/media/test/pipeline_integration_test.cc
+++ b/media/test/pipeline_integration_test.cc
@@ -65,80 +65,80 @@
 namespace media {
 
 #if BUILDFLAG(ENABLE_AV1_DECODER)
-constexpr int kAV110bitMp4FileDurationMs = 2735;
-constexpr int kAV1640WebMFileDurationMs = 2736;
+const int kAV110bitMp4FileDurationMs = 2735;
+const int kAV1640WebMFileDurationMs = 2736;
 #endif  // BUILDFLAG(ENABLE_AV1_DECODER)
 
 // Constants for the Media Source config change tests.
-constexpr int kAppendTimeSec = 1;
-constexpr int kAppendTimeMs = kAppendTimeSec * 1000;
-constexpr int k320WebMFileDurationMs = 2736;
-constexpr int k640WebMFileDurationMs = 2762;
-constexpr int kVP9WebMFileDurationMs = 2736;
-constexpr int kVP8AWebMFileDurationMs = 2734;
+const int kAppendTimeSec = 1;
+const int kAppendTimeMs = kAppendTimeSec * 1000;
+const int k320WebMFileDurationMs = 2736;
+const int k640WebMFileDurationMs = 2762;
+const int kVP9WebMFileDurationMs = 2736;
+const int kVP8AWebMFileDurationMs = 2734;
 
-constexpr char kSfxLosslessHash[] = "3.03,2.86,2.99,3.31,3.57,4.06,";
+static const char kSfxLosslessHash[] = "3.03,2.86,2.99,3.31,3.57,4.06,";
 
 #if defined(OPUS_FIXED_POINT)
 // NOTE: These hashes are specific to ARM devices, which use fixed-point Opus
 // implementation. x86 uses floating-point Opus, so x86 hashes won't match
-constexpr char kOpusSmallCodecDelayHash_1[] =
-    "-0.48,-0.09,1.27,1.06,1.54,-0.22,";
-
-#if defined(ARCH_CPU_ARM_FAMILY)
-constexpr char kOpusSmallCodecDelayHash_2[] = "0.29,0.15,-0.19,0.25,0.68,0.83,";
-constexpr char kOpusMonoOutputHash[] = "-2.39,-1.66,0.81,1.54,1.48,-0.91,";
-
-#if defined(ARCH_CPU_32BITS)
-constexpr char kOpusEndTrimmingHash_1[] =
-    "-4.58,-5.68,-6.53,-6.29,-4.35,-3.59,";
-constexpr char kOpusEndTrimmingHash_2[] =
-    "-11.93,-11.12,-8.26,-7.11,-7.85,-10.01,";
-constexpr char kOpusEndTrimmingHash_3[] =
-    "-13.33,-14.39,-13.69,-11.68,-10.19,-10.50,";
-#else   // Assume 64-bits for arm-generic configurations.
-constexpr char kOpusEndTrimmingHash_1[] =
+#if defined(ARCH_CPU_ARM64)
+static const char kOpusEndTrimmingHash_1[] =
     "-4.58,-5.68,-6.53,-6.28,-4.35,-3.59,";
-constexpr char kOpusEndTrimmingHash_2[] =
+static const char kOpusEndTrimmingHash_2[] =
     "-11.92,-11.11,-8.25,-7.10,-7.84,-10.00,";
-constexpr char kOpusEndTrimmingHash_3[] =
+static const char kOpusEndTrimmingHash_3[] =
     "-13.33,-14.38,-13.68,-11.66,-10.18,-10.49,";
-#endif  // defined(ARCH_CPU_32BITS)
-
-#else   // Assume X86 hashes:
-constexpr char kOpusEndTrimmingHash_1[] =
+static const char kOpusSmallCodecDelayHash_1[] =
+    "-0.48,-0.09,1.27,1.06,1.54,-0.22,";
+static const char kOpusSmallCodecDelayHash_2[] =
+    "0.29,0.15,-0.19,0.25,0.68,0.83,";
+static const char kOpusMonoOutputHash[] = "-2.39,-1.66,0.81,1.54,1.48,-0.91,";
+#else
+static const char kOpusEndTrimmingHash_1[] =
     "-4.57,-5.66,-6.52,-6.30,-4.37,-3.61,";
-constexpr char kOpusEndTrimmingHash_2[] =
+static const char kOpusEndTrimmingHash_2[] =
     "-11.91,-11.11,-8.27,-7.13,-7.86,-10.00,";
-constexpr char kOpusEndTrimmingHash_3[] =
+static const char kOpusEndTrimmingHash_3[] =
     "-13.31,-14.38,-13.70,-11.71,-10.21,-10.49,";
-constexpr char kOpusSmallCodecDelayHash_2[] = "0.29,0.14,-0.20,0.24,0.68,0.83,";
-constexpr char kOpusMonoOutputHash[] = "-2.41,-1.66,0.79,1.53,1.46,-0.91,";
-#endif  // defined(ARCH_CPU_ARM_FAMILY)
+static const char kOpusSmallCodecDelayHash_1[] =
+    "-0.48,-0.09,1.27,1.06,1.54,-0.22,";
+static const char kOpusSmallCodecDelayHash_2[] =
+    "0.29,0.14,-0.20,0.24,0.68,0.83,";
+static const char kOpusMonoOutputHash[] = "-2.41,-1.66,0.79,1.53,1.46,-0.91,";
+#endif  // defined(ARCH_CPU_ARM64)
 
-#else   // Use non-fixed point hashes:
+#else
 // Hash for a full playthrough of "opus-trimming-test.(webm|ogg)".
-constexpr char kOpusEndTrimmingHash_1[] =
+static const char kOpusEndTrimmingHash_1[] =
     "-4.57,-5.67,-6.52,-6.28,-4.34,-3.58,";
 // The above hash, plus an additional playthrough starting from T=1s.
-constexpr char kOpusEndTrimmingHash_2[] =
+static const char kOpusEndTrimmingHash_2[] =
     "-11.91,-11.10,-8.24,-7.08,-7.82,-9.99,";
 // The above hash, plus an additional playthrough starting from T=6.36s.
-constexpr char kOpusEndTrimmingHash_3[] =
+static const char kOpusEndTrimmingHash_3[] =
     "-13.31,-14.36,-13.66,-11.65,-10.16,-10.47,";
 // Hash for a full playthrough of "bear-opus.webm".
-constexpr char kOpusSmallCodecDelayHash_1[] =
+static const char kOpusSmallCodecDelayHash_1[] =
     "-0.47,-0.09,1.28,1.07,1.55,-0.22,";
 // The above hash, plus an additional playthrough starting from T=1.414s.
-constexpr char kOpusSmallCodecDelayHash_2[] = "0.31,0.15,-0.18,0.25,0.70,0.84,";
+static const char kOpusSmallCodecDelayHash_2[] =
+    "0.31,0.15,-0.18,0.25,0.70,0.84,";
 // For BasicPlaybackOpusWebmHashed_MonoOutput test case.
-constexpr char kOpusMonoOutputHash[] = "-2.36,-1.64,0.84,1.55,1.51,-0.90,";
+static const char kOpusMonoOutputHash[] = "-2.36,-1.64,0.84,1.55,1.51,-0.90,";
 #endif  // defined(OPUS_FIXED_POINT)
 
-#if BUILDFLAG(USE_PROPRIETARY_CODECS) && BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
-constexpr int k1280IsoFileDurationMs = 2736;
+#if BUILDFLAG(USE_PROPRIETARY_CODECS)
+const int k640IsoCencFileDurationMs = 2769;
+const int k1280IsoFileDurationMs = 2736;
 
-constexpr int k1280IsoAVC3FileDurationMs = 2736;
+// TODO(wolenetz): Update to 2769 once MSE endOfStream implementation no longer
+// truncates duration to the highest in intersection ranges, but compliantly to
+// the largest track buffer ranges end time across all tracks and SourceBuffers.
+// See https://crbug.com/639144.
+const int k1280IsoFileDurationMsAV = 2763;
+
+const int k1280IsoAVC3FileDurationMs = 2736;
 #endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
 
 // Return a timeline offset for bear-320x240-live.webm.
@@ -677,11 +677,11 @@
     {"bear-av1.webm", kAppendWholeFile, kVP9WebMFileDurationMs},
 #endif  // BUILDFLAG(ENABLE_AV1_DECODER)
 
-#if BUILDFLAG(USE_PROPRIETARY_CODECS) && BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
+#if BUILDFLAG(USE_PROPRIETARY_CODECS)
     // H264 AVC3 in MP4
     {"bear-1280x720-v_frag-avc3.mp4", kAppendWholeFile,
      k1280IsoAVC3FileDurationMs},
-#endif
+#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
 };
 
 INSTANTIATE_TEST_SUITE_P(
@@ -2181,6 +2181,14 @@
 }
 #endif  // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_WIN)
 
+TEST_F(PipelineIntegrationTest, BasicPlaybackHi10P) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear-320x180-hi10p.mp4"));
+
+  Play();
+
+  ASSERT_TRUE(WaitUntilOnEnded());
+}
+
 std::vector<std::unique_ptr<VideoDecoder>> CreateFailingVideoDecoder() {
   std::vector<std::unique_ptr<VideoDecoder>> failing_video_decoder;
   failing_video_decoder.push_back(std::make_unique<FailingVideoDecoder>());
@@ -2189,7 +2197,7 @@
 
 TEST_F(PipelineIntegrationTest, BasicFallback) {
   ASSERT_EQ(PIPELINE_OK,
-            Start("bear.webm", kNormal,
+            Start("bear.mp4", kNormal,
                   base::BindRepeating(&CreateFailingVideoDecoder)));
 
   Play();
@@ -2197,7 +2205,6 @@
   ASSERT_TRUE(WaitUntilOnEnded());
 }
 
-#if BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
 TEST_F(PipelineIntegrationTest, MSE_ConfigChange_MP4) {
   TestMediaSource source("bear-640x360-av_frag.mp4", kAppendWholeFile);
   EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
@@ -2218,13 +2225,6 @@
 
   EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
   EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
-
-  // TODO(wolenetz): Update to 2769 once MSE endOfStream implementation no
-  // longer truncates duration to the highest in intersection ranges, but
-  // compliantly to the largest track buffer ranges end time across all tracks
-  // and SourceBuffers. See https://crbug.com/639144.
-  constexpr int k1280IsoFileDurationMsAV = 2763;
-
   EXPECT_EQ(kAppendTimeMs + k1280IsoFileDurationMsAV,
             pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
 
@@ -2336,7 +2336,6 @@
   EXPECT_EQ(33, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
 
   // The second video was not added, so its time has not been added.
-  constexpr int k640IsoCencFileDurationMs = 2769;
   EXPECT_EQ(k640IsoCencFileDurationMs,
             pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
 
@@ -2345,13 +2344,6 @@
   EXPECT_EQ(CHUNK_DEMUXER_ERROR_APPEND_FAILED, WaitUntilEndedOrError());
   source.Shutdown();
 }
-#endif  // BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
-
-TEST_F(PipelineIntegrationTest, StereoAACMarkedAsMono) {
-  ASSERT_EQ(PIPELINE_OK, Start("mono_cpe.adts"));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-}
 #endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
 
 // Verify files which change configuration midstream fail gracefully.
@@ -2446,7 +2438,6 @@
 }
 
 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
-#if BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
 TEST_F(PipelineIntegrationTest, MSE_EncryptedPlayback_MP4_CENC_VideoOnly) {
   TestMediaSource source("bear-1280x720-v_frag-cenc.mp4", kAppendWholeFile);
   FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
@@ -2463,6 +2454,22 @@
   Stop();
 }
 
+TEST_F(PipelineIntegrationTest, MSE_EncryptedPlayback_MP4_CENC_AudioOnly) {
+  TestMediaSource source("bear-1280x720-a_frag-cenc.mp4", kAppendWholeFile);
+  FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
+  EXPECT_EQ(PIPELINE_OK,
+            StartPipelineWithEncryptedMedia(&source, &encrypted_media));
+
+  source.EndOfStream();
+  ASSERT_EQ(PIPELINE_OK, pipeline_status_);
+
+  Play();
+
+  ASSERT_TRUE(WaitUntilOnEnded());
+  source.Shutdown();
+  Stop();
+}
+
 TEST_F(PipelineIntegrationTest,
        MSE_EncryptedPlayback_NoEncryptedFrames_MP4_CENC_VideoOnly) {
   TestMediaSource source("bear-1280x720-v_frag-cenc_clear-all.mp4",
@@ -2499,24 +2506,6 @@
 #endif
 }
 
-#endif  // BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
-
-TEST_F(PipelineIntegrationTest, MSE_EncryptedPlayback_MP4_CENC_AudioOnly) {
-  TestMediaSource source("bear-1280x720-a_frag-cenc.mp4", kAppendWholeFile);
-  FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
-  EXPECT_EQ(PIPELINE_OK,
-            StartPipelineWithEncryptedMedia(&source, &encrypted_media));
-
-  source.EndOfStream();
-  ASSERT_EQ(PIPELINE_OK, pipeline_status_);
-
-  Play();
-
-  ASSERT_TRUE(WaitUntilOnEnded());
-  source.Shutdown();
-  Stop();
-}
-
 TEST_F(PipelineIntegrationTest, MSE_Mpeg2ts_MP3Audio_Mp4a_6B) {
   TestMediaSource source("bear-audio-mp4a.6B.ts",
                          "video/mp2t; codecs=\"mp4a.6B\"", kAppendWholeFile);
@@ -2562,8 +2551,6 @@
   Stop();
 }
 
-#if BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
-
 // Older packagers saved sample encryption auxiliary information in the
 // beginning of mdat box.
 TEST_F(PipelineIntegrationTest, MSE_EncryptedPlayback_MP4_CENC_MDAT_Video) {
@@ -2635,24 +2622,6 @@
   Stop();
 }
 
-TEST_F(PipelineIntegrationTest, MSE_BasicPlayback_VideoOnly_MP4_AVC3) {
-  TestMediaSource source("bear-1280x720-v_frag-avc3.mp4", kAppendWholeFile);
-  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
-  source.EndOfStream();
-
-  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
-  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
-  EXPECT_EQ(k1280IsoAVC3FileDurationMs,
-            pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
-
-  Play();
-
-  ASSERT_TRUE(WaitUntilOnEnded());
-  source.Shutdown();
-  Stop();
-}
-#endif  // BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
-
 TEST_F(PipelineIntegrationTest,
        MSE_EncryptedPlayback_MP4_CENC_KeyRotation_Audio) {
   TestMediaSource source("bear-1280x720-a_frag-cenc-key_rotation.mp4",
@@ -2670,6 +2639,23 @@
   Stop();
 }
 
+TEST_F(PipelineIntegrationTest, MSE_BasicPlayback_VideoOnly_MP4_AVC3) {
+  TestMediaSource source("bear-1280x720-v_frag-avc3.mp4", kAppendWholeFile);
+  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
+  source.EndOfStream();
+
+  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
+  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
+  EXPECT_EQ(k1280IsoAVC3FileDurationMs,
+            pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
+
+  Play();
+
+  ASSERT_TRUE(WaitUntilOnEnded());
+  source.Shutdown();
+  Stop();
+}
+
 TEST_F(PipelineIntegrationTest, MSE_BasicPlayback_VideoOnly_MP4_HEVC) {
   // HEVC demuxing might be enabled even on platforms that don't support HEVC
   // decoding. For those cases we'll get DECODER_ERROR_NOT_SUPPORTED, which
@@ -2806,6 +2792,45 @@
   ASSERT_TRUE(WaitUntilOnEnded());
 }
 
+#if BUILDFLAG(USE_PROPRIETARY_CODECS)
+TEST_F(PipelineIntegrationTest, Rotated_Metadata_0) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear_rotate_0.mp4"));
+  ASSERT_EQ(VIDEO_ROTATION_0,
+            metadata_.video_decoder_config.video_transformation().rotation);
+}
+
+TEST_F(PipelineIntegrationTest, Rotated_Metadata_90) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear_rotate_90.mp4"));
+  ASSERT_EQ(VIDEO_ROTATION_90,
+            metadata_.video_decoder_config.video_transformation().rotation);
+}
+
+TEST_F(PipelineIntegrationTest, Rotated_Metadata_180) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear_rotate_180.mp4"));
+  ASSERT_EQ(VIDEO_ROTATION_180,
+            metadata_.video_decoder_config.video_transformation().rotation);
+}
+
+TEST_F(PipelineIntegrationTest, Rotated_Metadata_270) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear_rotate_270.mp4"));
+  ASSERT_EQ(VIDEO_ROTATION_270,
+            metadata_.video_decoder_config.video_transformation().rotation);
+}
+
+TEST_F(PipelineIntegrationTest, Spherical) {
+  ASSERT_EQ(PIPELINE_OK, Start("spherical.mp4", kHashed));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+  EXPECT_HASH_EQ("1cb7f980020d99ea852e22dd6bd8d9de", GetVideoHash());
+}
+
+TEST_F(PipelineIntegrationTest, StereoAACMarkedAsMono) {
+  ASSERT_EQ(PIPELINE_OK, Start("mono_cpe.adts"));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+}
+#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
+
 // Verify audio decoder & renderer can handle aborted demuxer reads.
 TEST_F(PipelineIntegrationTest, MSE_ChunkDemuxerAbortRead_AudioOnly) {
   ASSERT_TRUE(TestSeekDuringRead("bear-320x240-audio-only.webm", 16384,
@@ -2919,6 +2944,17 @@
                         gfx::ColorSpace::CreateREC709());
 }
 
+#if BUILDFLAG(USE_PROPRIETARY_CODECS)
+// Verify that full-range H264 video has the right color space.
+TEST_F(PipelineIntegrationTest, Fullrange_H264) {
+  ASSERT_EQ(PIPELINE_OK, Start("blackwhite_yuvj420p.mp4"));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+  EXPECT_COLOR_SPACE_EQ(last_video_frame_color_space_,
+                        gfx::ColorSpace::CreateJpeg());
+}
+#endif
+
 TEST_F(PipelineIntegrationTest, HD_VP9_WebM) {
   ASSERT_EQ(PIPELINE_OK, Start("bear-1280x720.webm"));
   Play();
@@ -2973,15 +3009,6 @@
   ASSERT_TRUE(WaitUntilOnEnded());
 }
 
-TEST_F(PipelineIntegrationTest, BasicPlaybackPositiveStartTime) {
-  ASSERT_EQ(PIPELINE_OK, Start("nonzero-start-time.webm"));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-  ASSERT_EQ(base::Microseconds(396000), demuxer_->GetStartTime());
-}
-
-#if BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
-
 // Ensures audio-video playback with missing or negative timestamps fails
 // instead of crashing.  See http://crbug.com/396864.
 TEST_F(PipelineIntegrationTest, BasicPlaybackChainedOggVideo) {
@@ -3009,55 +3036,11 @@
   ASSERT_TRUE(WaitUntilOnEnded());
 }
 
-#if BUILDFLAG(USE_PROPRIETARY_CODECS)
-TEST_F(PipelineIntegrationTest, Rotated_Metadata_0) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear_rotate_0.mp4"));
-  ASSERT_EQ(VIDEO_ROTATION_0,
-            metadata_.video_decoder_config.video_transformation().rotation);
-}
-
-TEST_F(PipelineIntegrationTest, Rotated_Metadata_90) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear_rotate_90.mp4"));
-  ASSERT_EQ(VIDEO_ROTATION_90,
-            metadata_.video_decoder_config.video_transformation().rotation);
-}
-
-TEST_F(PipelineIntegrationTest, Rotated_Metadata_180) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear_rotate_180.mp4"));
-  ASSERT_EQ(VIDEO_ROTATION_180,
-            metadata_.video_decoder_config.video_transformation().rotation);
-}
-
-TEST_F(PipelineIntegrationTest, Rotated_Metadata_270) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear_rotate_270.mp4"));
-  ASSERT_EQ(VIDEO_ROTATION_270,
-            metadata_.video_decoder_config.video_transformation().rotation);
-}
-
-TEST_F(PipelineIntegrationTest, Spherical) {
-  ASSERT_EQ(PIPELINE_OK, Start("spherical.mp4", kHashed));
+TEST_F(PipelineIntegrationTest, BasicPlaybackPositiveStartTime) {
+  ASSERT_EQ(PIPELINE_OK, Start("nonzero-start-time.webm"));
   Play();
   ASSERT_TRUE(WaitUntilOnEnded());
-  EXPECT_HASH_EQ("1cb7f980020d99ea852e22dd6bd8d9de", GetVideoHash());
+  ASSERT_EQ(base::Microseconds(396000), demuxer_->GetStartTime());
 }
 
-TEST_F(PipelineIntegrationTest, BasicPlaybackHi10P) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear-320x180-hi10p.mp4"));
-
-  Play();
-
-  ASSERT_TRUE(WaitUntilOnEnded());
-}
-
-// Verify that full-range H264 video has the right color space.
-TEST_F(PipelineIntegrationTest, Fullrange_H264) {
-  ASSERT_EQ(PIPELINE_OK, Start("blackwhite_yuvj420p.mp4"));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-  EXPECT_COLOR_SPACE_EQ(last_video_frame_color_space_,
-                        gfx::ColorSpace::CreateJpeg());
-}
-#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
-#endif  // BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
-
 }  // namespace media
diff --git a/mojo/public/cpp/bindings/interface_endpoint_client.h b/mojo/public/cpp/bindings/interface_endpoint_client.h
index 052e4107..9520da44 100644
--- a/mojo/public/cpp/bindings/interface_endpoint_client.h
+++ b/mojo/public/cpp/bindings/interface_endpoint_client.h
@@ -343,7 +343,7 @@
 
   internal::ControlMessageProxy control_message_proxy_{this};
   internal::ControlMessageHandler control_message_handler_;
-  const char* interface_name_;
+  const char* const interface_name_;
   const MessageToMethodInfoCallback method_info_callback_;
   const MessageToMethodNameCallback method_name_callback_;
 
diff --git a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
index 6802bc1d1..8a83521c 100644
--- a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
+++ b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
@@ -459,6 +459,7 @@
       interface_name_(interface_name),
       method_info_callback_(method_info_callback),
       method_name_callback_(method_name_callback) {
+  DCHECK(interface_name_);
   DCHECK(handle_.is_valid());
   sequence_checker_.DetachFromSequence();
 
@@ -715,11 +716,7 @@
     return;
   encountered_error_ = true;
 
-  // TODO(dcheng): interface_name_ *should* never be null, but for the purposes
-  // of not introducing a new crash in code intended to help debug crashes, do a
-  // null check for safety.
-  DEBUG_ALIAS_FOR_CSTR(interface_name, interface_name_ ? interface_name_ : "",
-                       256);
+  DEBUG_ALIAS_FOR_CSTR(interface_name, interface_name_, 256);
 
   // Response callbacks may hold on to resource, and there's no need to keep
   // them alive any longer. Note that it's allowed that a pending response
diff --git a/net/cookies/cookie_store_change_unittest.h b/net/cookies/cookie_store_change_unittest.h
index a1b06fc5..be89df1 100644
--- a/net/cookies/cookie_store_change_unittest.h
+++ b/net/cookies/cookie_store_change_unittest.h
@@ -1780,16 +1780,14 @@
       "__Host-b=2; Secure; Path=/; Partitioned",
       CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
       absl::nullopt /* system_time */,
-      absl::make_optional(
-          CookiePartitionKey::FromURLForTesting(GURL("https://sub.foo.com"))));
+      CookiePartitionKey::FromURLForTesting(GURL("https://sub.foo.com")));
   // Partitioned cookie with a different partition key
   this->CreateAndSetCookie(
       cs, GURL("https://www.example.com"),
       "__Host-c=3; Secure; Path=/; Partitioned",
       CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
       absl::nullopt /* system_time */,
-      absl::make_optional(
-          CookiePartitionKey::FromURLForTesting(GURL("https://www.bar.com"))));
+      CookiePartitionKey::FromURLForTesting(GURL("https://www.bar.com")));
   this->DeliverChangeNotifications();
 
   ASSERT_EQ(2u, cookie_changes.size());
@@ -1817,8 +1815,7 @@
       "__Host-b=2; Secure; Path=/; Partitioned; Max-Age=7200",
       CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
       absl::nullopt /* system_time */,
-      absl::make_optional(
-          CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com"))));
+      CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com")));
   this->DeliverChangeNotifications();
   ASSERT_EQ(0u, other_cookie_changes.size());
   // Check that the other listener was invoked.
@@ -3067,16 +3064,14 @@
       "__Host-a=2; Secure; Path=/; Partitioned",
       CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
       absl::nullopt /* system_time */,
-      absl::make_optional(
-          CookiePartitionKey::FromURLForTesting(GURL("https://sub.foo.com"))));
+      CookiePartitionKey::FromURLForTesting(GURL("https://sub.foo.com")));
   // Partitioned cookie with a different partition key
   this->CreateAndSetCookie(
       cs, GURL("https://www.example.com"),
       "__Host-a=3; Secure; Path=/; Partitioned",
       CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
       absl::nullopt /* system_time */,
-      absl::make_optional(
-          CookiePartitionKey::FromURLForTesting(GURL("https://www.bar.com"))));
+      CookiePartitionKey::FromURLForTesting(GURL("https://www.bar.com")));
   this->DeliverChangeNotifications();
 
   ASSERT_EQ(2u, cookie_changes.size());
@@ -3103,8 +3098,7 @@
       "__Host-a=2; Secure; Path=/; Partitioned; Max-Age=7200",
       CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
       absl::nullopt /* system_time */,
-      absl::make_optional(
-          CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com"))));
+      CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com")));
   this->DeliverChangeNotifications();
   ASSERT_EQ(0u, other_cookie_changes.size());
   // Check that the other listener was invoked.
diff --git a/net/url_request/url_request_test_job.cc b/net/url_request/url_request_test_job.cc
index 4fc0612..10be229 100644
--- a/net/url_request/url_request_test_job.cc
+++ b/net/url_request/url_request_test_job.cc
@@ -287,7 +287,7 @@
       stage_ = DATA_AVAILABLE;
       // OK if ReadRawData wasn't called yet.
       if (async_buf_) {
-        int result = CopyDataForRead(async_buf_, async_buf_size_);
+        int result = CopyDataForRead(async_buf_.get(), async_buf_size_);
         if (result < 0)
           NOTREACHED() << "Reads should not fail in DATA_AVAILABLE.";
         if (NextReadAsync()) {
diff --git a/net/url_request/url_request_test_job.h b/net/url_request/url_request_test_job.h
index d464244f..a144685e9 100644
--- a/net/url_request/url_request_test_job.h
+++ b/net/url_request/url_request_test_job.h
@@ -173,7 +173,7 @@
   int offset_ = 0;
 
   // Holds the buffer for an asynchronous ReadRawData call
-  raw_ptr<IOBuffer> async_buf_ = nullptr;
+  scoped_refptr<IOBuffer> async_buf_;
   int async_buf_size_ = 0;
 
   LoadTimingInfo load_timing_info_;
diff --git a/remoting/client/notification/notification_client.cc b/remoting/client/notification/notification_client.cc
index 96ae833..94fbe60 100644
--- a/remoting/client/notification/notification_client.cc
+++ b/remoting/client/notification/notification_client.cc
@@ -214,13 +214,20 @@
     }
     if (done_ && is_message_translation_fetched_ &&
         is_link_translation_fetched_) {
-      std::move(done_).Run(true);
+      RunDoneCallback(true);
     }
   }
 
   void NotifyFetchFailed() {
     DCHECK(done_);
-    std::move(done_).Run(false);
+    RunDoneCallback(false);
+  }
+
+  void RunDoneCallback(bool arg) {
+    // Drop unowned resources before invoking callback destroying them.
+    out_link_translation_ = nullptr;
+    out_message_translation_ = nullptr;
+    std::move(done_).Run(arg);
   }
 
   std::string locale_;
diff --git a/remoting/client/notification/notification_client_unittest.cc b/remoting/client/notification/notification_client_unittest.cc
index 5fa22f3f..671b2060 100644
--- a/remoting/client/notification/notification_client_unittest.cc
+++ b/remoting/client/notification/notification_client_unittest.cc
@@ -106,8 +106,8 @@
         test_locale, should_ignore_dev_messages));
   }
 
-  raw_ptr<MockJsonFetcher> fetcher_;
   std::unique_ptr<NotificationClient> client_;
+  raw_ptr<MockJsonFetcher> fetcher_;  // Owned by `client_`.
 };
 
 TEST_F(NotificationClientTest, NoRule) {
@@ -438,4 +438,4 @@
   client_->GetNotification(/* user_email= */ "", callback.Get());
 }
 
-}  // namespace remoting
\ No newline at end of file
+}  // namespace remoting
diff --git a/testing/buildbot/chrome.gpu.fyi.json b/testing/buildbot/chrome.gpu.fyi.json
new file mode 100644
index 0000000..b881060b
--- /dev/null
+++ b/testing/buildbot/chrome.gpu.fyi.json
@@ -0,0 +1,652 @@
+{
+  "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {},
+  "AAAAA2 See generate_buildbot_json.py to make changes": {},
+  "Lacros FYI Release (eve)": {
+    "additional_compile_targets": [
+      "chrome"
+    ],
+    "isolated_scripts": [
+      {
+        "args": [
+          "context_lost",
+          "--show-stdout",
+          "--browser=lacros-chrome",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle",
+          "--deploy-lacros",
+          "--remote=variable_chromeos_device_hostname"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "context_lost_passthrough_tests Ash ToT",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "device_type": "eve",
+              "os": "ChromeOS",
+              "pool": "chrome.tests"
+            }
+          ],
+          "expiration": 21600,
+          "idempotent": false,
+          "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
+        "trigger_script": {
+          "script": "//testing/trigger_scripts/chromeos_device_trigger.py"
+        },
+        "variant_id": "Ash ToT"
+      },
+      {
+        "args": [
+          "gpu_process",
+          "--show-stdout",
+          "--browser=lacros-chrome",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--log-level=0 --js-flags=--expose-gc",
+          "--deploy-lacros",
+          "--remote=variable_chromeos_device_hostname"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "gpu_process_launch_tests Ash ToT",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "device_type": "eve",
+              "os": "ChromeOS",
+              "pool": "chrome.tests"
+            }
+          ],
+          "expiration": 21600,
+          "idempotent": false,
+          "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
+        "trigger_script": {
+          "script": "//testing/trigger_scripts/chromeos_device_trigger.py"
+        },
+        "variant_id": "Ash ToT"
+      },
+      {
+        "args": [
+          "hardware_accelerated_feature",
+          "--show-stdout",
+          "--browser=lacros-chrome",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--log-level=0 --js-flags=--expose-gc",
+          "--deploy-lacros",
+          "--remote=variable_chromeos_device_hostname"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "hardware_accelerated_feature_tests Ash ToT",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "device_type": "eve",
+              "os": "ChromeOS",
+              "pool": "chrome.tests"
+            }
+          ],
+          "expiration": 21600,
+          "idempotent": false,
+          "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
+        "trigger_script": {
+          "script": "//testing/trigger_scripts/chromeos_device_trigger.py"
+        },
+        "variant_id": "Ash ToT"
+      },
+      {
+        "args": [
+          "maps",
+          "--show-stdout",
+          "--browser=lacros-chrome",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle",
+          "--dont-restore-color-profile-after-test",
+          "--test-machine-name",
+          "${buildername}",
+          "--deploy-lacros",
+          "--remote=variable_chromeos_device_hostname",
+          "--git-revision=${got_revision}"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "maps_pixel_passthrough_test Ash ToT",
+        "precommit_args": [
+          "--gerrit-issue=${patch_issue}",
+          "--gerrit-patchset=${patch_set}",
+          "--buildbucket-id=${buildbucket_build_id}"
+        ],
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "device_type": "eve",
+              "os": "ChromeOS",
+              "pool": "chrome.tests"
+            }
+          ],
+          "expiration": 21600,
+          "idempotent": false,
+          "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
+        "trigger_script": {
+          "script": "//testing/trigger_scripts/chromeos_device_trigger.py"
+        },
+        "variant_id": "Ash ToT"
+      },
+      {
+        "args": [
+          "pixel",
+          "--show-stdout",
+          "--browser=lacros-chrome",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle",
+          "--dont-restore-color-profile-after-test",
+          "--test-machine-name",
+          "${buildername}",
+          "--deploy-lacros",
+          "--remote=variable_chromeos_device_hostname",
+          "--git-revision=${got_revision}"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "pixel_skia_gold_passthrough_test Ash ToT",
+        "precommit_args": [
+          "--gerrit-issue=${patch_issue}",
+          "--gerrit-patchset=${patch_set}",
+          "--buildbucket-id=${buildbucket_build_id}"
+        ],
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "device_type": "eve",
+              "os": "ChromeOS",
+              "pool": "chrome.tests"
+            }
+          ],
+          "expiration": 21600,
+          "idempotent": false,
+          "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
+        "trigger_script": {
+          "script": "//testing/trigger_scripts/chromeos_device_trigger.py"
+        },
+        "variant_id": "Ash ToT"
+      },
+      {
+        "args": [
+          "screenshot_sync",
+          "--show-stdout",
+          "--browser=lacros-chrome",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle",
+          "--dont-restore-color-profile-after-test",
+          "--deploy-lacros",
+          "--remote=variable_chromeos_device_hostname"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "screenshot_sync_passthrough_tests Ash ToT",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "device_type": "eve",
+              "os": "ChromeOS",
+              "pool": "chrome.tests"
+            }
+          ],
+          "expiration": 21600,
+          "idempotent": false,
+          "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
+        "trigger_script": {
+          "script": "//testing/trigger_scripts/chromeos_device_trigger.py"
+        },
+        "variant_id": "Ash ToT"
+      },
+      {
+        "args": [
+          "webgl2_conformance",
+          "--show-stdout",
+          "--browser=lacros-chrome",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--log-level=0 --js-flags=--expose-gc --use-gl=angle --use-angle=gles --use-cmd-decoder=passthrough --force_high_performance_gpu",
+          "--webgl-conformance-version=2.0.1",
+          "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json",
+          "--jobs=1",
+          "--deploy-lacros",
+          "--remote=variable_chromeos_device_hostname"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgl2_conformance_gles_passthrough_tests Ash ToT",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "device_type": "eve",
+              "os": "ChromeOS",
+              "pool": "chrome.tests"
+            }
+          ],
+          "expiration": 21600,
+          "idempotent": false,
+          "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 20
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
+        "trigger_script": {
+          "script": "//testing/trigger_scripts/chromeos_device_trigger.py"
+        },
+        "variant_id": "Ash ToT"
+      }
+    ]
+  },
+  "Lacros FYI Release (jacuzzi)": {
+    "additional_compile_targets": [
+      "chrome"
+    ],
+    "isolated_scripts": [
+      {
+        "args": [
+          "context_lost",
+          "--show-stdout",
+          "--browser=lacros-chrome",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle",
+          "--deploy-lacros",
+          "--remote=variable_chromeos_device_hostname"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "context_lost_passthrough_tests Ash ToT",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "device_type": "jacuzzi",
+              "os": "ChromeOS",
+              "pool": "chrome.tests"
+            }
+          ],
+          "expiration": 21600,
+          "idempotent": false,
+          "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
+        "trigger_script": {
+          "script": "//testing/trigger_scripts/chromeos_device_trigger.py"
+        },
+        "variant_id": "Ash ToT"
+      },
+      {
+        "args": [
+          "gpu_process",
+          "--show-stdout",
+          "--browser=lacros-chrome",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--log-level=0 --js-flags=--expose-gc",
+          "--deploy-lacros",
+          "--remote=variable_chromeos_device_hostname"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "gpu_process_launch_tests Ash ToT",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "device_type": "jacuzzi",
+              "os": "ChromeOS",
+              "pool": "chrome.tests"
+            }
+          ],
+          "expiration": 21600,
+          "idempotent": false,
+          "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
+        "trigger_script": {
+          "script": "//testing/trigger_scripts/chromeos_device_trigger.py"
+        },
+        "variant_id": "Ash ToT"
+      },
+      {
+        "args": [
+          "hardware_accelerated_feature",
+          "--show-stdout",
+          "--browser=lacros-chrome",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--log-level=0 --js-flags=--expose-gc",
+          "--deploy-lacros",
+          "--remote=variable_chromeos_device_hostname"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "hardware_accelerated_feature_tests Ash ToT",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "device_type": "jacuzzi",
+              "os": "ChromeOS",
+              "pool": "chrome.tests"
+            }
+          ],
+          "expiration": 21600,
+          "idempotent": false,
+          "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
+        "trigger_script": {
+          "script": "//testing/trigger_scripts/chromeos_device_trigger.py"
+        },
+        "variant_id": "Ash ToT"
+      },
+      {
+        "args": [
+          "maps",
+          "--show-stdout",
+          "--browser=lacros-chrome",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle",
+          "--dont-restore-color-profile-after-test",
+          "--test-machine-name",
+          "${buildername}",
+          "--deploy-lacros",
+          "--remote=variable_chromeos_device_hostname",
+          "--git-revision=${got_revision}"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "maps_pixel_passthrough_test Ash ToT",
+        "precommit_args": [
+          "--gerrit-issue=${patch_issue}",
+          "--gerrit-patchset=${patch_set}",
+          "--buildbucket-id=${buildbucket_build_id}"
+        ],
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "device_type": "jacuzzi",
+              "os": "ChromeOS",
+              "pool": "chrome.tests"
+            }
+          ],
+          "expiration": 21600,
+          "idempotent": false,
+          "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
+        "trigger_script": {
+          "script": "//testing/trigger_scripts/chromeos_device_trigger.py"
+        },
+        "variant_id": "Ash ToT"
+      },
+      {
+        "args": [
+          "pixel",
+          "--show-stdout",
+          "--browser=lacros-chrome",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle",
+          "--dont-restore-color-profile-after-test",
+          "--test-machine-name",
+          "${buildername}",
+          "--deploy-lacros",
+          "--remote=variable_chromeos_device_hostname",
+          "--git-revision=${got_revision}"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "pixel_skia_gold_passthrough_test Ash ToT",
+        "precommit_args": [
+          "--gerrit-issue=${patch_issue}",
+          "--gerrit-patchset=${patch_set}",
+          "--buildbucket-id=${buildbucket_build_id}"
+        ],
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "device_type": "jacuzzi",
+              "os": "ChromeOS",
+              "pool": "chrome.tests"
+            }
+          ],
+          "expiration": 21600,
+          "idempotent": false,
+          "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
+        "trigger_script": {
+          "script": "//testing/trigger_scripts/chromeos_device_trigger.py"
+        },
+        "variant_id": "Ash ToT"
+      },
+      {
+        "args": [
+          "screenshot_sync",
+          "--show-stdout",
+          "--browser=lacros-chrome",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle",
+          "--dont-restore-color-profile-after-test",
+          "--deploy-lacros",
+          "--remote=variable_chromeos_device_hostname"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "screenshot_sync_passthrough_tests Ash ToT",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "device_type": "jacuzzi",
+              "os": "ChromeOS",
+              "pool": "chrome.tests"
+            }
+          ],
+          "expiration": 21600,
+          "idempotent": false,
+          "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
+        "trigger_script": {
+          "script": "//testing/trigger_scripts/chromeos_device_trigger.py"
+        },
+        "variant_id": "Ash ToT"
+      },
+      {
+        "args": [
+          "webgl2_conformance",
+          "--show-stdout",
+          "--browser=lacros-chrome",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--log-level=0 --js-flags=--expose-gc --use-gl=angle --use-angle=gles --use-cmd-decoder=passthrough --force_high_performance_gpu",
+          "--webgl-conformance-version=2.0.1",
+          "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json",
+          "--jobs=1",
+          "--deploy-lacros",
+          "--remote=variable_chromeos_device_hostname"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgl2_conformance_gles_passthrough_tests Ash ToT",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "device_type": "jacuzzi",
+              "os": "ChromeOS",
+              "pool": "chrome.tests"
+            }
+          ],
+          "expiration": 21600,
+          "idempotent": false,
+          "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 20
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
+        "trigger_script": {
+          "script": "//testing/trigger_scripts/chromeos_device_trigger.py"
+        },
+        "variant_id": "Ash ToT"
+      }
+    ]
+  }
+}
diff --git a/testing/buildbot/chrome.json b/testing/buildbot/chrome.json
index d4a03a0..6451ab75 100644
--- a/testing/buildbot/chrome.json
+++ b/testing/buildbot/chrome.json
@@ -1555,7 +1555,7 @@
         "args": [],
         "autotest_name": "tast.chrome-from-tls",
         "cros_board": "octopus",
-        "cros_img": "octopus-release/R114-15419.0.0",
+        "cros_img": "octopus-release/R114-15408.0.0",
         "name": "chrome_all_tast_tests OCTOPUS_RELEASE_CHROME_FROM_TLS_LKGM",
         "shards": 10,
         "swarming": {},
@@ -1794,7 +1794,7 @@
       {
         "args": [],
         "cros_board": "dedede",
-        "cros_img": "dedede-release/R114-15419.0.0",
+        "cros_img": "dedede-release/R114-15410.0.0",
         "name": "lacros_all_tast_tests DEDEDE_RELEASE_LKGM",
         "resultdb": {
           "enable": true,
@@ -1811,7 +1811,7 @@
       {
         "args": [],
         "cros_board": "dedede",
-        "cros_img": "dedede-release/R114-15416.0.0",
+        "cros_img": "dedede-release/R113-15393.12.0",
         "name": "lacros_all_tast_tests DEDEDE_RELEASE_DEV",
         "resultdb": {
           "enable": true,
@@ -1828,7 +1828,7 @@
       {
         "args": [],
         "cros_board": "dedede",
-        "cros_img": "dedede-release/R113-15393.12.0",
+        "cros_img": "dedede-release/R112-15359.37.0",
         "name": "lacros_all_tast_tests DEDEDE_RELEASE_BETA",
         "resultdb": {
           "enable": true,
@@ -1862,7 +1862,7 @@
       {
         "args": [],
         "cros_board": "eve",
-        "cros_img": "eve-release/R114-15419.0.0",
+        "cros_img": "eve-release/R114-15410.0.0",
         "name": "lacros_all_tast_tests EVE_RELEASE_LKGM",
         "resultdb": {
           "enable": true,
@@ -1879,7 +1879,7 @@
       {
         "args": [],
         "cros_board": "eve",
-        "cros_img": "eve-release/R114-15416.0.0",
+        "cros_img": "eve-release/R113-15393.12.0",
         "name": "lacros_all_tast_tests EVE_RELEASE_DEV",
         "resultdb": {
           "enable": true,
@@ -1896,7 +1896,7 @@
       {
         "args": [],
         "cros_board": "eve",
-        "cros_img": "eve-release/R113-15393.12.0",
+        "cros_img": "eve-release/R112-15359.37.0",
         "name": "lacros_all_tast_tests EVE_RELEASE_BETA",
         "resultdb": {
           "enable": true,
@@ -1913,7 +1913,7 @@
       {
         "args": [],
         "cros_board": "eve",
-        "cros_img": "eve-release/R112-15359.45.0",
+        "cros_img": "eve-release/R111-15329.59.0",
         "name": "lacros_all_tast_tests EVE_RELEASE_STABLE",
         "resultdb": {
           "enable": true,
@@ -1965,7 +1965,7 @@
       {
         "args": [],
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-release/R114-15419.0.0",
+        "cros_img": "jacuzzi-release/R114-15410.0.0",
         "name": "lacros_all_tast_tests JACUZZI_RELEASE_LKGM",
         "resultdb": {
           "enable": true,
@@ -1982,7 +1982,7 @@
       {
         "args": [],
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-release/R114-15416.0.0",
+        "cros_img": "jacuzzi-release/R113-15393.12.0",
         "name": "lacros_all_tast_tests JACUZZI_RELEASE_DEV",
         "resultdb": {
           "enable": true,
@@ -1999,7 +1999,7 @@
       {
         "args": [],
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-release/R113-15393.12.0",
+        "cros_img": "jacuzzi-release/R112-15359.37.0",
         "name": "lacros_all_tast_tests JACUZZI_RELEASE_BETA",
         "resultdb": {
           "enable": true,
@@ -2016,7 +2016,7 @@
       {
         "args": [],
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-release/R112-15359.45.0",
+        "cros_img": "jacuzzi-release/R111-15329.59.0",
         "name": "lacros_all_tast_tests JACUZZI_RELEASE_STABLE",
         "resultdb": {
           "enable": true,
@@ -2068,7 +2068,7 @@
       {
         "args": [],
         "cros_board": "herobrine",
-        "cros_img": "herobrine-release/R114-15419.0.0",
+        "cros_img": "herobrine-release/R114-15410.0.0",
         "name": "lacros_all_tast_tests HEROBRINE_RELEASE_LKGM",
         "resultdb": {
           "enable": true,
diff --git a/testing/buildbot/chromium.angle.json b/testing/buildbot/chromium.angle.json
index ff2353e..97ceb06a 100644
--- a/testing/buildbot/chromium.angle.json
+++ b/testing/buildbot/chromium.angle.json
@@ -82,7 +82,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "containment_type": "AUTO",
@@ -139,7 +139,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "containment_type": "AUTO",
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index b5bf0b66..567cc76d 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -1620,7 +1620,7 @@
         "args": [],
         "bucket": "chromiumos-image-archive",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-public/R114-15419.0.0",
+        "cros_img": "jacuzzi-public/R114-15410.0.0",
         "name": "lacros_all_tast_tests JACUZZI_PUBLIC_LKGM",
         "resultdb": {
           "enable": true,
@@ -1650,7 +1650,7 @@
         "args": [],
         "bucket": "chromiumos-image-archive",
         "cros_board": "kevin",
-        "cros_img": "kevin64-public/R114-15419.0.0",
+        "cros_img": "kevin64-public/R114-15410.0.0",
         "name": "lacros_all_tast_tests KEVIN64_PUBLIC_LKGM",
         "resultdb": {
           "enable": true,
@@ -5618,9 +5618,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_v114.0.5712.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5712.0",
+        "description": "Run with ash-chrome version 114.0.5713.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -5631,8 +5631,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5712.0",
-              "revision": "version:114.0.5712.0"
+              "location": "lacros_version_skew_tests_v114.0.5713.0",
+              "revision": "version:114.0.5713.0"
             }
           ],
           "dimension_sets": [
@@ -5783,9 +5783,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5712.0",
+        "description": "Run with ash-chrome version 114.0.5713.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -5796,8 +5796,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5712.0",
-              "revision": "version:114.0.5712.0"
+              "location": "lacros_version_skew_tests_v114.0.5713.0",
+              "revision": "version:114.0.5713.0"
             }
           ],
           "dimension_sets": [
@@ -5930,9 +5930,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5712.0",
+        "description": "Run with ash-chrome version 114.0.5713.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -5943,8 +5943,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5712.0",
-              "revision": "version:114.0.5712.0"
+              "location": "lacros_version_skew_tests_v114.0.5713.0",
+              "revision": "version:114.0.5713.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.clang.json b/testing/buildbot/chromium.clang.json
index 5a3dc4be..be5168b 100644
--- a/testing/buildbot/chromium.clang.json
+++ b/testing/buildbot/chromium.clang.json
@@ -38447,7 +38447,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -38498,7 +38498,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -38549,7 +38549,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -38600,7 +38600,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -38651,7 +38651,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -38702,7 +38702,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -38753,7 +38753,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -38804,7 +38804,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -38855,7 +38855,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -38906,7 +38906,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -38957,7 +38957,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -39008,7 +39008,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -39059,7 +39059,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -39110,7 +39110,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -39161,7 +39161,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -39212,7 +39212,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -39263,7 +39263,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -39314,7 +39314,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -39385,7 +39385,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -39431,7 +39431,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -39477,7 +39477,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -39523,7 +39523,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -39569,7 +39569,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -39615,7 +39615,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -39661,7 +39661,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -39707,7 +39707,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -39753,7 +39753,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -39799,7 +39799,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -39845,7 +39845,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -39891,7 +39891,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -39937,7 +39937,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -39983,7 +39983,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -40029,7 +40029,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -40075,7 +40075,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -40121,7 +40121,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -40167,7 +40167,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json
index d697c5b6..66caf37 100644
--- a/testing/buildbot/chromium.coverage.json
+++ b/testing/buildbot/chromium.coverage.json
@@ -10033,7 +10033,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10086,7 +10086,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10139,7 +10139,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10192,7 +10192,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10245,7 +10245,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10298,7 +10298,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10351,7 +10351,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10404,7 +10404,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10457,7 +10457,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10510,7 +10510,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10563,7 +10563,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10616,7 +10616,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10669,7 +10669,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10722,7 +10722,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10775,7 +10775,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10828,7 +10828,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10881,7 +10881,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10934,7 +10934,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10987,7 +10987,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11040,7 +11040,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11093,7 +11093,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11146,7 +11146,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11199,7 +11199,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11252,7 +11252,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11305,7 +11305,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11358,7 +11358,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11411,7 +11411,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11464,7 +11464,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11517,7 +11517,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11570,7 +11570,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11623,7 +11623,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11676,7 +11676,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11729,7 +11729,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11782,7 +11782,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11835,7 +11835,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11888,7 +11888,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11941,7 +11941,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11994,7 +11994,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12047,7 +12047,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12100,7 +12100,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12153,7 +12153,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12206,7 +12206,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12260,7 +12260,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12314,7 +12314,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12368,7 +12368,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12422,7 +12422,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12476,7 +12476,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12530,7 +12530,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12584,7 +12584,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12638,7 +12638,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12692,7 +12692,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12747,7 +12747,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12802,7 +12802,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12857,7 +12857,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12912,7 +12912,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12967,7 +12967,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13022,7 +13022,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13077,7 +13077,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13132,7 +13132,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13187,7 +13187,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13242,7 +13242,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13297,7 +13297,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13352,7 +13352,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13407,7 +13407,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13462,7 +13462,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13517,7 +13517,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13572,7 +13572,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13627,7 +13627,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13682,7 +13682,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13737,7 +13737,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13792,7 +13792,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13847,7 +13847,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13902,7 +13902,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13957,7 +13957,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14012,7 +14012,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14066,7 +14066,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14120,7 +14120,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14174,7 +14174,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14228,7 +14228,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14282,7 +14282,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14336,7 +14336,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14390,7 +14390,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14444,7 +14444,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14499,7 +14499,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14554,7 +14554,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14609,7 +14609,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14664,7 +14664,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14719,7 +14719,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14774,7 +14774,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14829,7 +14829,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14883,7 +14883,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14936,7 +14936,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14989,7 +14989,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15042,7 +15042,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15095,7 +15095,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15148,7 +15148,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15201,7 +15201,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15254,7 +15254,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15307,7 +15307,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15360,7 +15360,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15414,7 +15414,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15469,7 +15469,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15524,7 +15524,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15579,7 +15579,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15634,7 +15634,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15689,7 +15689,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15744,7 +15744,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15799,7 +15799,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15853,7 +15853,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15906,7 +15906,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15959,7 +15959,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16013,7 +16013,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16067,7 +16067,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16120,7 +16120,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16174,7 +16174,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16228,7 +16228,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16282,7 +16282,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16336,7 +16336,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16390,7 +16390,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16444,7 +16444,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16498,7 +16498,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16552,7 +16552,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16605,7 +16605,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16658,7 +16658,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16711,7 +16711,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16764,7 +16764,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16817,7 +16817,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16870,7 +16870,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16923,7 +16923,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16976,7 +16976,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17029,7 +17029,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17082,7 +17082,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17135,7 +17135,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17188,7 +17188,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17242,7 +17242,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17296,7 +17296,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17350,7 +17350,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17404,7 +17404,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17458,7 +17458,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17512,7 +17512,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17566,7 +17566,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17620,7 +17620,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17673,7 +17673,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17726,7 +17726,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17779,7 +17779,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17832,7 +17832,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17885,7 +17885,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17938,7 +17938,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17991,7 +17991,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18044,7 +18044,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18097,7 +18097,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18150,7 +18150,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18203,7 +18203,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18256,7 +18256,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18309,7 +18309,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18362,7 +18362,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18415,7 +18415,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18468,7 +18468,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18521,7 +18521,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18574,7 +18574,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18627,7 +18627,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18680,7 +18680,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18733,7 +18733,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18786,7 +18786,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18839,7 +18839,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18892,7 +18892,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18945,7 +18945,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18998,7 +18998,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19051,7 +19051,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19104,7 +19104,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19157,7 +19157,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19210,7 +19210,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19263,7 +19263,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19316,7 +19316,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19369,7 +19369,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19422,7 +19422,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19475,7 +19475,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19528,7 +19528,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19581,7 +19581,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19634,7 +19634,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19687,7 +19687,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19740,7 +19740,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19793,7 +19793,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19846,7 +19846,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19899,7 +19899,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19952,7 +19952,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20005,7 +20005,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20058,7 +20058,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20111,7 +20111,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20164,7 +20164,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20217,7 +20217,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20270,7 +20270,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20323,7 +20323,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20376,7 +20376,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20429,7 +20429,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20482,7 +20482,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20535,7 +20535,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20588,7 +20588,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20641,7 +20641,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20694,7 +20694,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -25212,9 +25212,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_v114.0.5712.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5712.0",
+        "description": "Run with ash-chrome version 114.0.5713.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -25225,8 +25225,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5712.0",
-              "revision": "version:114.0.5712.0"
+              "location": "lacros_version_skew_tests_v114.0.5713.0",
+              "revision": "version:114.0.5713.0"
             }
           ],
           "dimension_sets": [
@@ -25377,9 +25377,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5712.0",
+        "description": "Run with ash-chrome version 114.0.5713.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -25390,8 +25390,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5712.0",
-              "revision": "version:114.0.5712.0"
+              "location": "lacros_version_skew_tests_v114.0.5713.0",
+              "revision": "version:114.0.5713.0"
             }
           ],
           "dimension_sets": [
@@ -25524,9 +25524,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5712.0",
+        "description": "Run with ash-chrome version 114.0.5713.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -25537,8 +25537,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5712.0",
-              "revision": "version:114.0.5712.0"
+              "location": "lacros_version_skew_tests_v114.0.5713.0",
+              "revision": "version:114.0.5713.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index ffa5ac6..7e2b986 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -5841,7 +5841,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -5892,7 +5892,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -5943,7 +5943,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -5995,7 +5995,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -6047,7 +6047,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -6098,7 +6098,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -6149,7 +6149,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -6200,7 +6200,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -6251,7 +6251,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -6302,7 +6302,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -6353,7 +6353,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -6404,7 +6404,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -6455,7 +6455,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -6506,7 +6506,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -6557,7 +6557,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -6608,7 +6608,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -6659,7 +6659,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -6710,7 +6710,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -6761,7 +6761,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -6812,7 +6812,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -6863,7 +6863,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -6914,7 +6914,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -6965,7 +6965,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -7016,7 +7016,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -7067,7 +7067,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -7118,7 +7118,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -7169,7 +7169,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -7220,7 +7220,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -7271,7 +7271,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -7322,7 +7322,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -7373,7 +7373,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -7424,7 +7424,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -7475,7 +7475,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -7526,7 +7526,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -7577,7 +7577,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -7628,7 +7628,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -7679,7 +7679,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -7730,7 +7730,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -7781,7 +7781,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -7832,7 +7832,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -7883,7 +7883,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -7934,7 +7934,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -7985,7 +7985,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -8036,7 +8036,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -8087,7 +8087,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -8138,7 +8138,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -8189,7 +8189,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -8240,7 +8240,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -8291,7 +8291,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -8342,7 +8342,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -8393,7 +8393,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -8444,7 +8444,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -8495,7 +8495,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -8546,7 +8546,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -8597,7 +8597,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -8648,7 +8648,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -8699,7 +8699,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -8750,7 +8750,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -8801,7 +8801,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -8852,7 +8852,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -8903,7 +8903,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -8954,7 +8954,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -9005,7 +9005,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -9056,7 +9056,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -9107,7 +9107,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -9158,7 +9158,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -9209,7 +9209,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -9260,7 +9260,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -9311,7 +9311,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -9362,7 +9362,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -9413,7 +9413,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -9464,7 +9464,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -9515,7 +9515,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -9566,7 +9566,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -9617,7 +9617,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -9668,7 +9668,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -9719,7 +9719,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -9770,7 +9770,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -9821,7 +9821,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -9872,7 +9872,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -9923,7 +9923,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -9974,7 +9974,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10025,7 +10025,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10076,7 +10076,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10127,7 +10127,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10178,7 +10178,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10229,7 +10229,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10280,7 +10280,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10331,7 +10331,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10382,7 +10382,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10433,7 +10433,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10484,7 +10484,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10535,7 +10535,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10586,7 +10586,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10637,7 +10637,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10688,7 +10688,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10745,7 +10745,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10799,7 +10799,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10853,7 +10853,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10908,7 +10908,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10963,7 +10963,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11018,7 +11018,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11073,7 +11073,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11128,7 +11128,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11183,7 +11183,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11237,7 +11237,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11291,7 +11291,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11346,7 +11346,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11401,7 +11401,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11456,7 +11456,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11511,7 +11511,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11565,7 +11565,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11619,7 +11619,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11673,7 +11673,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11732,7 +11732,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11783,7 +11783,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11834,7 +11834,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11885,7 +11885,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11936,7 +11936,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11987,7 +11987,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12038,7 +12038,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12089,7 +12089,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12140,7 +12140,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12191,7 +12191,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12242,7 +12242,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12293,7 +12293,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12344,7 +12344,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12395,7 +12395,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12446,7 +12446,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12497,7 +12497,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12548,7 +12548,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12599,7 +12599,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12653,7 +12653,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12707,7 +12707,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12761,7 +12761,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12815,7 +12815,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12870,7 +12870,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12925,7 +12925,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12980,7 +12980,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13035,7 +13035,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13090,7 +13090,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13145,7 +13145,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13200,7 +13200,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13255,7 +13255,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13310,7 +13310,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13365,7 +13365,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13419,7 +13419,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13473,7 +13473,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13527,7 +13527,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13582,7 +13582,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13637,7 +13637,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13689,7 +13689,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13740,7 +13740,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13791,7 +13791,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13842,7 +13842,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13896,7 +13896,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13951,7 +13951,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14006,7 +14006,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14058,7 +14058,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14109,7 +14109,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14161,7 +14161,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14215,7 +14215,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14269,7 +14269,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14323,7 +14323,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14374,7 +14374,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14425,7 +14425,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14476,7 +14476,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14527,7 +14527,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14578,7 +14578,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14632,7 +14632,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14686,7 +14686,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14740,7 +14740,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14794,7 +14794,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14845,7 +14845,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14896,7 +14896,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14947,7 +14947,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14998,7 +14998,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15049,7 +15049,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15100,7 +15100,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15151,7 +15151,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15202,7 +15202,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15253,7 +15253,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15304,7 +15304,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15355,7 +15355,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15406,7 +15406,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15457,7 +15457,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15508,7 +15508,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15559,7 +15559,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15610,7 +15610,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15661,7 +15661,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15712,7 +15712,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15763,7 +15763,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15814,7 +15814,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15865,7 +15865,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15916,7 +15916,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15967,7 +15967,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16018,7 +16018,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16073,7 +16073,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16128,7 +16128,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16183,7 +16183,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16234,7 +16234,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16285,7 +16285,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16336,7 +16336,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16387,7 +16387,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16438,7 +16438,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16489,7 +16489,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16540,7 +16540,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16591,7 +16591,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16643,7 +16643,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16695,7 +16695,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16748,7 +16748,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16801,7 +16801,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16854,7 +16854,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16906,7 +16906,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16958,7 +16958,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17010,7 +17010,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17062,7 +17062,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17113,7 +17113,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17165,7 +17165,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17217,7 +17217,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17268,7 +17268,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17319,7 +17319,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17371,7 +17371,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17422,7 +17422,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17473,7 +17473,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17524,7 +17524,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17575,7 +17575,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17626,7 +17626,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17677,7 +17677,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17728,7 +17728,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17779,7 +17779,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17830,7 +17830,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17887,7 +17887,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17940,7 +17940,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17993,7 +17993,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18046,7 +18046,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18099,7 +18099,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18152,7 +18152,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18205,7 +18205,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18258,7 +18258,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18311,7 +18311,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18364,7 +18364,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18417,7 +18417,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18470,7 +18470,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18523,7 +18523,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18576,7 +18576,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18629,7 +18629,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18682,7 +18682,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18735,7 +18735,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18788,7 +18788,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18842,7 +18842,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18896,7 +18896,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18950,7 +18950,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19005,7 +19005,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19060,7 +19060,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19115,7 +19115,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19170,7 +19170,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19225,7 +19225,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19280,7 +19280,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19334,7 +19334,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19388,7 +19388,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19443,7 +19443,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19497,7 +19497,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19550,7 +19550,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19604,7 +19604,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19659,7 +19659,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19713,7 +19713,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19766,7 +19766,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19819,7 +19819,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19873,7 +19873,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19927,7 +19927,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19980,7 +19980,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20034,7 +20034,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20088,7 +20088,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20141,7 +20141,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20194,7 +20194,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20247,7 +20247,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20300,7 +20300,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20354,7 +20354,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20408,7 +20408,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20461,7 +20461,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20514,7 +20514,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20567,7 +20567,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20620,7 +20620,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20673,7 +20673,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20726,7 +20726,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20779,7 +20779,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20832,7 +20832,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20885,7 +20885,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20938,7 +20938,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20991,7 +20991,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -21044,7 +21044,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -21097,7 +21097,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -21150,7 +21150,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -21203,7 +21203,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -21256,7 +21256,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -21309,7 +21309,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -21362,7 +21362,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -21417,7 +21417,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -21483,7 +21483,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -21534,7 +21534,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -21585,7 +21585,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -21636,7 +21636,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -21687,7 +21687,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -21738,7 +21738,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -21789,7 +21789,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -21840,7 +21840,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -21891,7 +21891,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -21942,7 +21942,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -21993,7 +21993,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -22044,7 +22044,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -22095,7 +22095,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -22146,7 +22146,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -22197,7 +22197,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -22248,7 +22248,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -22299,7 +22299,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -22350,7 +22350,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -22404,7 +22404,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -22458,7 +22458,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -22512,7 +22512,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -22566,7 +22566,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -22620,7 +22620,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -22675,7 +22675,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -22730,7 +22730,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -22785,7 +22785,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -22840,7 +22840,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -22895,7 +22895,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -22950,7 +22950,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -23005,7 +23005,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -23060,7 +23060,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -23115,7 +23115,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -23170,7 +23170,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -23225,7 +23225,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -23279,7 +23279,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -23333,7 +23333,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -23387,7 +23387,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -23441,7 +23441,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -23496,7 +23496,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -23551,7 +23551,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -23606,7 +23606,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -23658,7 +23658,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -23709,7 +23709,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -23760,7 +23760,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -23811,7 +23811,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -23865,7 +23865,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -23920,7 +23920,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -23975,7 +23975,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -24030,7 +24030,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -24082,7 +24082,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -24134,7 +24134,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -24185,7 +24185,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -24237,7 +24237,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -24291,7 +24291,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -24345,7 +24345,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -24399,7 +24399,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -24453,7 +24453,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -24505,7 +24505,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -24557,7 +24557,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -24608,7 +24608,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -24659,7 +24659,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -24710,7 +24710,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -24761,7 +24761,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -24812,7 +24812,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -24866,7 +24866,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -24920,7 +24920,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -24974,7 +24974,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -25025,7 +25025,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -25076,7 +25076,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -25127,7 +25127,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -25178,7 +25178,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -25229,7 +25229,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -25280,7 +25280,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -25331,7 +25331,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -25382,7 +25382,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -25433,7 +25433,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -25484,7 +25484,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -25535,7 +25535,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -25586,7 +25586,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -25637,7 +25637,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -25688,7 +25688,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -25739,7 +25739,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -25790,7 +25790,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -25841,7 +25841,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -25892,7 +25892,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -25943,7 +25943,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -25994,7 +25994,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -26045,7 +26045,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -26096,7 +26096,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -26147,7 +26147,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -26198,7 +26198,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -26263,7 +26263,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -26316,7 +26316,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -26369,7 +26369,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -26422,7 +26422,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -26475,7 +26475,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -26528,7 +26528,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -26581,7 +26581,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -26634,7 +26634,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -26687,7 +26687,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -26740,7 +26740,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -26793,7 +26793,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -26846,7 +26846,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -26899,7 +26899,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -26952,7 +26952,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -27005,7 +27005,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -27058,7 +27058,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -27111,7 +27111,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -27164,7 +27164,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -27218,7 +27218,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -27272,7 +27272,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -27326,7 +27326,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -27380,7 +27380,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -27435,7 +27435,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -27490,7 +27490,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -27545,7 +27545,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -27600,7 +27600,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -27655,7 +27655,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -27710,7 +27710,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -27765,7 +27765,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -27820,7 +27820,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -27875,7 +27875,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -27929,7 +27929,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -27983,7 +27983,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -28037,7 +28037,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -28092,7 +28092,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -28147,7 +28147,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -28201,7 +28201,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -28254,7 +28254,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -28307,7 +28307,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -28360,7 +28360,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -28414,7 +28414,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -28469,7 +28469,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -28524,7 +28524,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -28578,7 +28578,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -28632,7 +28632,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -28685,7 +28685,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -28739,7 +28739,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -28793,7 +28793,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -28847,7 +28847,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -28901,7 +28901,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -28955,7 +28955,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -29009,7 +29009,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -29062,7 +29062,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -29115,7 +29115,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -29168,7 +29168,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -29221,7 +29221,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -29274,7 +29274,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -29328,7 +29328,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -29382,7 +29382,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -29436,7 +29436,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -29489,7 +29489,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -29542,7 +29542,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -29595,7 +29595,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -29648,7 +29648,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -29701,7 +29701,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -29754,7 +29754,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -29807,7 +29807,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -29860,7 +29860,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -29913,7 +29913,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -29966,7 +29966,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -30019,7 +30019,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -30072,7 +30072,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -30125,7 +30125,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -30178,7 +30178,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -30231,7 +30231,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -30284,7 +30284,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -30337,7 +30337,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -30390,7 +30390,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -30443,7 +30443,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -30496,7 +30496,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -30549,7 +30549,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -30602,7 +30602,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -30655,7 +30655,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -30708,7 +30708,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -31093,7 +31093,7 @@
         "args": [],
         "bucket": "chromiumos-image-archive",
         "cros_board": "octopus",
-        "cros_img": "octopus-public/R114-15419.0.0",
+        "cros_img": "octopus-public/R114-15410.0.0",
         "name": "lacros_all_tast_tests OCTOPUS_PUBLIC_LKGM",
         "resultdb": {
           "enable": true,
@@ -31111,7 +31111,7 @@
         "args": [],
         "bucket": "chromiumos-image-archive",
         "cros_board": "eve",
-        "cros_img": "eve-public/R114-15419.0.0",
+        "cros_img": "eve-public/R114-15410.0.0",
         "name": "lacros_all_tast_tests EVE_PUBLIC_LKGM",
         "resultdb": {
           "enable": true,
@@ -31136,7 +31136,7 @@
         "args": [],
         "bucket": "chromiumos-image-archive",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-public/R114-15419.0.0",
+        "cros_img": "jacuzzi-public/R114-15410.0.0",
         "name": "lacros_all_tast_tests JACUZZI_PUBLIC_LKGM",
         "resultdb": {
           "enable": true,
@@ -31154,7 +31154,7 @@
         "args": [],
         "bucket": "chromiumos-image-archive",
         "cros_board": "kevin",
-        "cros_img": "kevin64-public/R114-15419.0.0",
+        "cros_img": "kevin64-public/R114-15410.0.0",
         "name": "lacros_all_tast_tests KEVIN64_PUBLIC_LKGM",
         "resultdb": {
           "enable": true,
@@ -31179,7 +31179,7 @@
         "args": [],
         "bucket": "chromiumos-image-archive",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-public/R114-15419.0.0",
+        "cros_img": "jacuzzi-public/R114-15410.0.0",
         "name": "lacros_all_tast_tests JACUZZI_PUBLIC_LKGM",
         "resultdb": {
           "enable": true,
@@ -31197,7 +31197,7 @@
         "args": [],
         "bucket": "chromiumos-image-archive",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-public/R114-15419.0.0",
+        "cros_img": "jacuzzi-public/R114-15410.0.0",
         "name": "lacros_all_tast_tests JACUZZI_CQ_PUBLIC_LKGM",
         "public_builder": "cros_test_platform_public",
         "public_builder_bucket": "testplatform-public",
@@ -31217,7 +31217,7 @@
         "args": [],
         "bucket": "chromiumos-image-archive",
         "cros_board": "kevin",
-        "cros_img": "kevin64-public/R114-15419.0.0",
+        "cros_img": "kevin64-public/R114-15410.0.0",
         "name": "lacros_all_tast_tests KEVIN64_PUBLIC_LKGM",
         "resultdb": {
           "enable": true,
@@ -33946,9 +33946,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_v114.0.5712.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5712.0",
+        "description": "Run with ash-chrome version 114.0.5713.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -33958,8 +33958,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5712.0",
-              "revision": "version:114.0.5712.0"
+              "location": "lacros_version_skew_tests_v114.0.5713.0",
+              "revision": "version:114.0.5713.0"
             }
           ],
           "dimension_sets": [
@@ -34111,9 +34111,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5712.0",
+        "description": "Run with ash-chrome version 114.0.5713.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -34123,8 +34123,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5712.0",
-              "revision": "version:114.0.5712.0"
+              "location": "lacros_version_skew_tests_v114.0.5713.0",
+              "revision": "version:114.0.5713.0"
             }
           ],
           "dimension_sets": [
@@ -34258,9 +34258,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5712.0",
+        "description": "Run with ash-chrome version 114.0.5713.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -34270,8 +34270,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5712.0",
-              "revision": "version:114.0.5712.0"
+              "location": "lacros_version_skew_tests_v114.0.5713.0",
+              "revision": "version:114.0.5713.0"
             }
           ],
           "dimension_sets": [
@@ -35698,9 +35698,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_v114.0.5712.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5712.0",
+        "description": "Run with ash-chrome version 114.0.5713.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -35710,8 +35710,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5712.0",
-              "revision": "version:114.0.5712.0"
+              "location": "lacros_version_skew_tests_v114.0.5713.0",
+              "revision": "version:114.0.5713.0"
             }
           ],
           "dimension_sets": [
@@ -35863,9 +35863,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5712.0",
+        "description": "Run with ash-chrome version 114.0.5713.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -35875,8 +35875,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5712.0",
-              "revision": "version:114.0.5712.0"
+              "location": "lacros_version_skew_tests_v114.0.5713.0",
+              "revision": "version:114.0.5713.0"
             }
           ],
           "dimension_sets": [
@@ -36010,9 +36010,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5712.0",
+        "description": "Run with ash-chrome version 114.0.5713.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -36022,8 +36022,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5712.0",
-              "revision": "version:114.0.5712.0"
+              "location": "lacros_version_skew_tests_v114.0.5713.0",
+              "revision": "version:114.0.5713.0"
             }
           ],
           "dimension_sets": [
@@ -36739,9 +36739,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_v114.0.5712.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5712.0",
+        "description": "Run with ash-chrome version 114.0.5713.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -36751,8 +36751,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5712.0",
-              "revision": "version:114.0.5712.0"
+              "location": "lacros_version_skew_tests_v114.0.5713.0",
+              "revision": "version:114.0.5713.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json
index 117c17eb9..6650242 100644
--- a/testing/buildbot/chromium.mac.json
+++ b/testing/buildbot/chromium.mac.json
@@ -10440,7 +10440,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10493,7 +10493,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10546,7 +10546,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10599,7 +10599,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10652,7 +10652,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10705,7 +10705,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10758,7 +10758,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10811,7 +10811,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10864,7 +10864,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10917,7 +10917,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -10970,7 +10970,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11023,7 +11023,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11077,7 +11077,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11131,7 +11131,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11184,7 +11184,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11237,7 +11237,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11290,7 +11290,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11344,7 +11344,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11397,7 +11397,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11450,7 +11450,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11503,7 +11503,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11557,7 +11557,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11610,7 +11610,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11663,7 +11663,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11716,7 +11716,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11769,7 +11769,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11822,7 +11822,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11875,7 +11875,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11928,7 +11928,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -11981,7 +11981,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12034,7 +12034,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12087,7 +12087,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12140,7 +12140,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12193,7 +12193,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12246,7 +12246,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12299,7 +12299,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12359,7 +12359,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12412,7 +12412,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12465,7 +12465,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12518,7 +12518,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12571,7 +12571,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12624,7 +12624,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12677,7 +12677,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12730,7 +12730,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12783,7 +12783,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12836,7 +12836,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12889,7 +12889,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12942,7 +12942,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -12995,7 +12995,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13048,7 +13048,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13101,7 +13101,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13154,7 +13154,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13207,7 +13207,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13260,7 +13260,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13314,7 +13314,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13368,7 +13368,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13422,7 +13422,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13476,7 +13476,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13530,7 +13530,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13585,7 +13585,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13640,7 +13640,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13695,7 +13695,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13750,7 +13750,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13805,7 +13805,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13860,7 +13860,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13915,7 +13915,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -13970,7 +13970,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14025,7 +14025,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14080,7 +14080,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14135,7 +14135,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14190,7 +14190,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14244,7 +14244,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14298,7 +14298,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14352,7 +14352,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14406,7 +14406,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14461,7 +14461,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14516,7 +14516,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14571,7 +14571,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14625,7 +14625,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14678,7 +14678,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14731,7 +14731,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14784,7 +14784,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14838,7 +14838,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14893,7 +14893,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14948,7 +14948,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15003,7 +15003,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15057,7 +15057,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15110,7 +15110,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15164,7 +15164,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15218,7 +15218,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15272,7 +15272,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15326,7 +15326,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15380,7 +15380,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15433,7 +15433,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15486,7 +15486,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15539,7 +15539,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15592,7 +15592,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15645,7 +15645,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15699,7 +15699,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15753,7 +15753,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15807,7 +15807,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15861,7 +15861,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15914,7 +15914,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15967,7 +15967,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16020,7 +16020,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16073,7 +16073,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16126,7 +16126,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16179,7 +16179,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16232,7 +16232,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16285,7 +16285,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16338,7 +16338,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16391,7 +16391,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16444,7 +16444,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16497,7 +16497,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16550,7 +16550,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16603,7 +16603,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16656,7 +16656,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16709,7 +16709,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16762,7 +16762,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16815,7 +16815,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16868,7 +16868,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16921,7 +16921,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16974,7 +16974,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17027,7 +17027,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17080,7 +17080,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17133,7 +17133,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17192,7 +17192,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17243,7 +17243,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17294,7 +17294,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17345,7 +17345,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17396,7 +17396,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17447,7 +17447,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17498,7 +17498,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17549,7 +17549,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17600,7 +17600,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17651,7 +17651,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17702,7 +17702,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17753,7 +17753,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17807,7 +17807,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17861,7 +17861,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17916,7 +17916,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17970,7 +17970,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18025,7 +18025,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18080,7 +18080,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18135,7 +18135,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18191,7 +18191,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18246,7 +18246,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18301,7 +18301,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18357,7 +18357,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18412,7 +18412,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18466,7 +18466,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18521,7 +18521,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18575,7 +18575,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18630,7 +18630,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18686,7 +18686,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18738,7 +18738,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18789,7 +18789,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18840,7 +18840,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18891,7 +18891,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -18945,7 +18945,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19000,7 +19000,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19056,7 +19056,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19109,7 +19109,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19163,7 +19163,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19217,7 +19217,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19272,7 +19272,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19323,7 +19323,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19374,7 +19374,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19425,7 +19425,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19476,7 +19476,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19530,7 +19530,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19584,7 +19584,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19635,7 +19635,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19686,7 +19686,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19737,7 +19737,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19788,7 +19788,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19839,7 +19839,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19890,7 +19890,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19941,7 +19941,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -19992,7 +19992,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20043,7 +20043,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20094,7 +20094,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20145,7 +20145,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20196,7 +20196,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20247,7 +20247,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20298,7 +20298,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20349,7 +20349,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20400,7 +20400,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20451,7 +20451,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20502,7 +20502,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20553,7 +20553,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -20604,7 +20604,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index dddfaba..8912b3c1 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -14344,7 +14344,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14395,7 +14395,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14446,7 +14446,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14497,7 +14497,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14548,7 +14548,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14599,7 +14599,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14650,7 +14650,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14701,7 +14701,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14752,7 +14752,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14803,7 +14803,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14854,7 +14854,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14905,7 +14905,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -14956,7 +14956,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15007,7 +15007,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15058,7 +15058,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15109,7 +15109,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15160,7 +15160,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15211,7 +15211,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15262,7 +15262,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15313,7 +15313,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15364,7 +15364,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15415,7 +15415,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15466,7 +15466,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15518,7 +15518,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15570,7 +15570,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15621,7 +15621,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15672,7 +15672,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15723,7 +15723,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15774,7 +15774,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15825,7 +15825,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15876,7 +15876,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15927,7 +15927,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -15978,7 +15978,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16029,7 +16029,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16080,7 +16080,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16131,7 +16131,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16182,7 +16182,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16233,7 +16233,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16284,7 +16284,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16335,7 +16335,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16386,7 +16386,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16437,7 +16437,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16488,7 +16488,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16539,7 +16539,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16590,7 +16590,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16641,7 +16641,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16692,7 +16692,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -16743,7 +16743,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -17723,12 +17723,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_v114.0.5712.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 114.0.5712.0",
+        "description": "Run with ash-chrome version 114.0.5713.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -17739,8 +17739,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5712.0",
-              "revision": "version:114.0.5712.0"
+              "location": "lacros_version_skew_tests_v114.0.5713.0",
+              "revision": "version:114.0.5713.0"
             }
           ],
           "dimension_sets": [
@@ -17908,12 +17908,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 114.0.5712.0",
+        "description": "Run with ash-chrome version 114.0.5713.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -17924,8 +17924,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5712.0",
-              "revision": "version:114.0.5712.0"
+              "location": "lacros_version_skew_tests_v114.0.5713.0",
+              "revision": "version:114.0.5713.0"
             }
           ],
           "dimension_sets": [
@@ -18070,12 +18070,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5712.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 114.0.5712.0",
+        "description": "Run with ash-chrome version 114.0.5713.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -18086,8 +18086,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5712.0",
-              "revision": "version:114.0.5712.0"
+              "location": "lacros_version_skew_tests_v114.0.5713.0",
+              "revision": "version:114.0.5713.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.rust.json b/testing/buildbot/chromium.rust.json
index de2db9a..f462b9b 100644
--- a/testing/buildbot/chromium.rust.json
+++ b/testing/buildbot/chromium.rust.json
@@ -693,7 +693,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -734,7 +734,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -775,7 +775,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -816,7 +816,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -857,7 +857,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -899,7 +899,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -941,7 +941,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -986,7 +986,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.webrtc.fyi.json b/testing/buildbot/chromium.webrtc.fyi.json
index 87390401..aab066f 100644
--- a/testing/buildbot/chromium.webrtc.fyi.json
+++ b/testing/buildbot/chromium.webrtc.fyi.json
@@ -720,7 +720,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
@@ -771,7 +771,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff"
+              "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/filters/android.emulator_12.chrome_public_test_apk.filter b/testing/buildbot/filters/android.emulator_12.chrome_public_test_apk.filter
index 4e4163c..c618df2 100644
--- a/testing/buildbot/filters/android.emulator_12.chrome_public_test_apk.filter
+++ b/testing/buildbot/filters/android.emulator_12.chrome_public_test_apk.filter
@@ -61,3 +61,6 @@
 -org.chromium.chrome.browser.tabmodel.UndoTabModelTest.testOpenRecentlyClosedTabMultiWindow
 -org.chromium.chrome.browser.tabmodel.UndoTabModelTest.testOpenRecentlyClosedTabMultiWindowFallback
 -org.chromium.chrome.browser.tasks.tab_management.TabSwitcherMultiWindowTest.*
+
+# crbug.com/1195129
+-org.chromium.chrome.browser.omnibox.suggestions.SwitchToTabTest.testSwitchToTabSuggestion
diff --git a/testing/buildbot/filters/android.emulator_12l.chrome_public_test_apk.filter b/testing/buildbot/filters/android.emulator_12l.chrome_public_test_apk.filter
index b35e2213..fb8aea67 100644
--- a/testing/buildbot/filters/android.emulator_12l.chrome_public_test_apk.filter
+++ b/testing/buildbot/filters/android.emulator_12l.chrome_public_test_apk.filter
@@ -85,3 +85,9 @@
 
 # crbug.com/1432049
 -org.chromium.chrome.browser.tasks.tab_management.TabGridDialogTest.testSelectionEditorPosition
+
+# crbug.com/1195129
+-org.chromium.chrome.browser.omnibox.suggestions.SwitchToTabTest.testSwitchToTabSuggestion
+
+# crbug.com/1432785
+-org.chromium.chrome.browser.ContentViewFocusTest.testHideSelectionOnPhoneTabSwiping
diff --git a/testing/buildbot/filters/lacros-device.webgl2_conformance_gles_passthrough_tests.filter b/testing/buildbot/filters/lacros-device.webgl2_conformance_gles_passthrough_tests.filter
new file mode 100644
index 0000000..dddbb79
--- /dev/null
+++ b/testing/buildbot/filters/lacros-device.webgl2_conformance_gles_passthrough_tests.filter
@@ -0,0 +1,4 @@
+# Small test suite due to limited capacity to run Lacros on devices.
+
+conformance/attribs/*
+conformance2/attribs/*
diff --git a/testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter b/testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter
index 1b5abac..ec174cf 100644
--- a/testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter
+++ b/testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter
@@ -3,3 +3,7 @@
 # If you want to disable a test only for version skew testing,
 # you should add the test here, not in the source code.
 
+# ash-chrome < M114 has an older "fake shill" which doesn't mark other services
+# as "idle" when connecting a new service.
+-NetworkingPrivateChromeOSApiTest.OnNetworksChangedEventConnect
+
diff --git a/testing/buildbot/generate_buildbot_json.py b/testing/buildbot/generate_buildbot_json.py
index c199135..5b66c3bc 100755
--- a/testing/buildbot/generate_buildbot_json.py
+++ b/testing/buildbot/generate_buildbot_json.py
@@ -1674,8 +1674,8 @@
     # Similar to get_builders_that_do_not_actually_exist above, but for
     # waterfalls defined in internal configs.
     return [
-        'chrome', 'chrome.pgo', 'internal.chrome.fyi', 'internal.chromeos.fyi',
-        'internal.soda'
+        'chrome', 'chrome.pgo', 'chrome.gpu.fyi', 'internal.chrome.fyi',
+        'internal.chromeos.fyi', 'internal.soda'
     ]
 
   def check_input_file_consistency(self, verbose=False):
diff --git a/testing/buildbot/internal.chromeos.fyi.json b/testing/buildbot/internal.chromeos.fyi.json
index a8641e4c..b4aaca4 100644
--- a/testing/buildbot/internal.chromeos.fyi.json
+++ b/testing/buildbot/internal.chromeos.fyi.json
@@ -1117,7 +1117,7 @@
         "args": [],
         "autotest_name": "tast.chrome-from-tls",
         "cros_board": "brya",
-        "cros_img": "brya-release/R114-15419.0.0",
+        "cros_img": "brya-release/R114-15407.0.0",
         "name": "chrome_all_tast_tests BRYA_RELEASE_LKGM",
         "shards": 10,
         "swarming": {},
@@ -1163,7 +1163,7 @@
         "args": [],
         "autotest_name": "tast.chrome-from-tls",
         "cros_board": "octopus",
-        "cros_img": "octopus-release/R114-15419.0.0",
+        "cros_img": "octopus-release/R114-15408.0.0",
         "name": "chrome_all_tast_tests OCTOPUS_RELEASE_CHROME_FROM_TLS_LKGM",
         "shards": 10,
         "swarming": {},
@@ -1186,7 +1186,7 @@
         "args": [],
         "autotest_name": "tast.chrome-from-tls",
         "cros_board": "trogdor",
-        "cros_img": "trogdor-release/R114-15419.0.0",
+        "cros_img": "trogdor-release/R114-15407.0.0",
         "name": "chrome_all_tast_tests TROGDOR_RELEASE_LKGM",
         "shards": 10,
         "swarming": {},
@@ -1209,7 +1209,7 @@
         "args": [],
         "autotest_name": "tast.chrome-from-tls",
         "cros_board": "volteer",
-        "cros_img": "volteer-release/R114-15419.0.0",
+        "cros_img": "volteer-release/R114-15407.0.0",
         "name": "chrome_all_tast_tests VOLTEER_RELEASE_LKGM",
         "shards": 10,
         "swarming": {},
@@ -1229,7 +1229,7 @@
       {
         "args": [],
         "cros_board": "octopus",
-        "cros_img": "octopus-release/R114-15419.0.0",
+        "cros_img": "octopus-release/R114-15410.0.0",
         "name": "lacros_fyi_tast_tests OCTOPUS_RELEASE_LKGM",
         "swarming": {},
         "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
@@ -1241,7 +1241,7 @@
       {
         "args": [],
         "cros_board": "octopus",
-        "cros_img": "octopus-release/R114-15416.0.0",
+        "cros_img": "octopus-release/R113-15393.12.0",
         "name": "lacros_fyi_tast_tests OCTOPUS_RELEASE_DEV",
         "swarming": {},
         "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
@@ -1253,7 +1253,7 @@
       {
         "args": [],
         "cros_board": "octopus",
-        "cros_img": "octopus-release/R113-15393.12.0",
+        "cros_img": "octopus-release/R112-15359.37.0",
         "name": "lacros_fyi_tast_tests OCTOPUS_RELEASE_BETA",
         "swarming": {},
         "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
@@ -1265,7 +1265,7 @@
       {
         "args": [],
         "cros_board": "octopus",
-        "cros_img": "octopus-release/R112-15359.45.0",
+        "cros_img": "octopus-release/R111-15329.59.0",
         "name": "lacros_fyi_tast_tests OCTOPUS_RELEASE_STABLE",
         "swarming": {},
         "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
@@ -1277,7 +1277,7 @@
       {
         "args": [],
         "cros_board": "octopus",
-        "cros_img": "octopus-release/R114-15419.0.0",
+        "cros_img": "octopus-release/R114-15410.0.0",
         "name": "ozone_unittests OCTOPUS_RELEASE_LKGM",
         "swarming": {},
         "test": "ozone_unittests",
@@ -1288,7 +1288,7 @@
       {
         "args": [],
         "cros_board": "octopus",
-        "cros_img": "octopus-release/R114-15416.0.0",
+        "cros_img": "octopus-release/R113-15393.12.0",
         "name": "ozone_unittests OCTOPUS_RELEASE_DEV",
         "swarming": {},
         "test": "ozone_unittests",
@@ -1299,7 +1299,7 @@
       {
         "args": [],
         "cros_board": "octopus",
-        "cros_img": "octopus-release/R113-15393.12.0",
+        "cros_img": "octopus-release/R112-15359.37.0",
         "name": "ozone_unittests OCTOPUS_RELEASE_BETA",
         "swarming": {},
         "test": "ozone_unittests",
@@ -1310,7 +1310,7 @@
       {
         "args": [],
         "cros_board": "octopus",
-        "cros_img": "octopus-release/R112-15359.45.0",
+        "cros_img": "octopus-release/R111-15329.59.0",
         "name": "ozone_unittests OCTOPUS_RELEASE_STABLE",
         "swarming": {},
         "test": "ozone_unittests",
@@ -1328,7 +1328,7 @@
       {
         "args": [],
         "cros_board": "hana",
-        "cros_img": "hana-release/R114-15419.0.0",
+        "cros_img": "hana-release/R114-15410.0.0",
         "name": "lacros_all_tast_tests HANA_RELEASE_LKGM",
         "swarming": {},
         "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
@@ -1340,7 +1340,7 @@
       {
         "args": [],
         "cros_board": "hana",
-        "cros_img": "hana-release/R114-15416.0.0",
+        "cros_img": "hana-release/R113-15393.12.0",
         "name": "lacros_all_tast_tests HANA_RELEASE_DEV",
         "swarming": {},
         "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
@@ -1352,7 +1352,7 @@
       {
         "args": [],
         "cros_board": "hana",
-        "cros_img": "hana-release/R113-15393.12.0",
+        "cros_img": "hana-release/R112-15359.37.0",
         "name": "lacros_all_tast_tests HANA_RELEASE_BETA",
         "swarming": {},
         "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
@@ -1364,7 +1364,7 @@
       {
         "args": [],
         "cros_board": "hana",
-        "cros_img": "hana-release/R112-15359.45.0",
+        "cros_img": "hana-release/R111-15329.59.0",
         "name": "lacros_all_tast_tests HANA_RELEASE_STABLE",
         "swarming": {},
         "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
@@ -1376,7 +1376,7 @@
       {
         "args": [],
         "cros_board": "strongbad",
-        "cros_img": "strongbad-release/R114-15419.0.0",
+        "cros_img": "strongbad-release/R114-15410.0.0",
         "name": "lacros_all_tast_tests STRONGBAD_RELEASE_LKGM",
         "swarming": {},
         "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
@@ -1388,7 +1388,7 @@
       {
         "args": [],
         "cros_board": "strongbad",
-        "cros_img": "strongbad-release/R114-15416.0.0",
+        "cros_img": "strongbad-release/R113-15393.12.0",
         "name": "lacros_all_tast_tests strongbad_RELEASE_DEV",
         "swarming": {},
         "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
@@ -1400,7 +1400,7 @@
       {
         "args": [],
         "cros_board": "strongbad",
-        "cros_img": "strongbad-release/R113-15393.12.0",
+        "cros_img": "strongbad-release/R112-15359.37.0",
         "name": "lacros_all_tast_tests STRONGBAD_RELEASE_BETA",
         "swarming": {},
         "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
@@ -1412,7 +1412,7 @@
       {
         "args": [],
         "cros_board": "strongbad",
-        "cros_img": "strongbad-release/R112-15359.45.0",
+        "cros_img": "strongbad-release/R111-15329.59.0",
         "name": "lacros_all_tast_tests STRONGBAD_RELEASE_STABLE",
         "swarming": {},
         "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
@@ -1424,7 +1424,7 @@
       {
         "args": [],
         "cros_board": "hana",
-        "cros_img": "hana-release/R114-15419.0.0",
+        "cros_img": "hana-release/R114-15410.0.0",
         "name": "ozone_unittests HANA_RELEASE_LKGM",
         "swarming": {},
         "test": "ozone_unittests",
@@ -1435,7 +1435,7 @@
       {
         "args": [],
         "cros_board": "hana",
-        "cros_img": "hana-release/R114-15416.0.0",
+        "cros_img": "hana-release/R113-15393.12.0",
         "name": "ozone_unittests HANA_RELEASE_DEV",
         "swarming": {},
         "test": "ozone_unittests",
@@ -1446,7 +1446,7 @@
       {
         "args": [],
         "cros_board": "hana",
-        "cros_img": "hana-release/R113-15393.12.0",
+        "cros_img": "hana-release/R112-15359.37.0",
         "name": "ozone_unittests HANA_RELEASE_BETA",
         "swarming": {},
         "test": "ozone_unittests",
@@ -1457,7 +1457,7 @@
       {
         "args": [],
         "cros_board": "hana",
-        "cros_img": "hana-release/R112-15359.45.0",
+        "cros_img": "hana-release/R111-15329.59.0",
         "name": "ozone_unittests HANA_RELEASE_STABLE",
         "swarming": {},
         "test": "ozone_unittests",
@@ -1468,7 +1468,7 @@
       {
         "args": [],
         "cros_board": "strongbad",
-        "cros_img": "strongbad-release/R114-15419.0.0",
+        "cros_img": "strongbad-release/R114-15410.0.0",
         "name": "ozone_unittests STRONGBAD_RELEASE_LKGM",
         "swarming": {},
         "test": "ozone_unittests",
@@ -1479,7 +1479,7 @@
       {
         "args": [],
         "cros_board": "strongbad",
-        "cros_img": "strongbad-release/R114-15416.0.0",
+        "cros_img": "strongbad-release/R113-15393.12.0",
         "name": "ozone_unittests strongbad_RELEASE_DEV",
         "swarming": {},
         "test": "ozone_unittests",
@@ -1490,7 +1490,7 @@
       {
         "args": [],
         "cros_board": "strongbad",
-        "cros_img": "strongbad-release/R113-15393.12.0",
+        "cros_img": "strongbad-release/R112-15359.37.0",
         "name": "ozone_unittests STRONGBAD_RELEASE_BETA",
         "swarming": {},
         "test": "ozone_unittests",
@@ -1501,7 +1501,7 @@
       {
         "args": [],
         "cros_board": "strongbad",
-        "cros_img": "strongbad-release/R112-15359.45.0",
+        "cros_img": "strongbad-release/R111-15329.59.0",
         "name": "ozone_unittests STRONGBAD_RELEASE_STABLE",
         "swarming": {},
         "test": "ozone_unittests",
@@ -1512,7 +1512,7 @@
       {
         "args": [],
         "cros_board": "hana",
-        "cros_img": "hana-release/R114-15419.0.0",
+        "cros_img": "hana-release/R114-15410.0.0",
         "name": "viz_unittests HANA_RELEASE_LKGM",
         "swarming": {},
         "test": "viz_unittests",
@@ -1523,7 +1523,7 @@
       {
         "args": [],
         "cros_board": "hana",
-        "cros_img": "hana-release/R114-15416.0.0",
+        "cros_img": "hana-release/R113-15393.12.0",
         "name": "viz_unittests HANA_RELEASE_DEV",
         "swarming": {},
         "test": "viz_unittests",
@@ -1534,7 +1534,7 @@
       {
         "args": [],
         "cros_board": "hana",
-        "cros_img": "hana-release/R113-15393.12.0",
+        "cros_img": "hana-release/R112-15359.37.0",
         "name": "viz_unittests HANA_RELEASE_BETA",
         "swarming": {},
         "test": "viz_unittests",
@@ -1545,7 +1545,7 @@
       {
         "args": [],
         "cros_board": "hana",
-        "cros_img": "hana-release/R112-15359.45.0",
+        "cros_img": "hana-release/R111-15329.59.0",
         "name": "viz_unittests HANA_RELEASE_STABLE",
         "swarming": {},
         "test": "viz_unittests",
@@ -1556,7 +1556,7 @@
       {
         "args": [],
         "cros_board": "strongbad",
-        "cros_img": "strongbad-release/R114-15419.0.0",
+        "cros_img": "strongbad-release/R114-15410.0.0",
         "name": "viz_unittests STRONGBAD_RELEASE_LKGM",
         "swarming": {},
         "test": "viz_unittests",
@@ -1567,7 +1567,7 @@
       {
         "args": [],
         "cros_board": "strongbad",
-        "cros_img": "strongbad-release/R114-15416.0.0",
+        "cros_img": "strongbad-release/R113-15393.12.0",
         "name": "viz_unittests strongbad_RELEASE_DEV",
         "swarming": {},
         "test": "viz_unittests",
@@ -1578,7 +1578,7 @@
       {
         "args": [],
         "cros_board": "strongbad",
-        "cros_img": "strongbad-release/R113-15393.12.0",
+        "cros_img": "strongbad-release/R112-15359.37.0",
         "name": "viz_unittests STRONGBAD_RELEASE_BETA",
         "swarming": {},
         "test": "viz_unittests",
@@ -1589,7 +1589,7 @@
       {
         "args": [],
         "cros_board": "strongbad",
-        "cros_img": "strongbad-release/R112-15359.45.0",
+        "cros_img": "strongbad-release/R111-15329.59.0",
         "name": "viz_unittests STRONGBAD_RELEASE_STABLE",
         "swarming": {},
         "test": "viz_unittests",
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl
index f02b884..f2142308 100644
--- a/testing/buildbot/mixins.pyl
+++ b/testing/buildbot/mixins.pyl
@@ -404,6 +404,14 @@
       ],
     },
   },
+  'chromeos-eve': {
+    'swarming': {
+      'dimensions': {
+        'os': 'ChromeOS',
+        'device_type': 'eve',
+      },
+    },
+  },
   'chromeos-jacuzzi': {
     'swarming': {
       'dimensions': {
@@ -1010,7 +1018,7 @@
         {
           "cipd_package": 'infra/tools/mac_toolchain/${platform}',
           'location': '.',
-          'revision': 'git_revision:5468d28877d7106d8ab4f7e23b784578ffc86aff',
+          'revision': 'git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118',
         },
       ],
     },
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index 037e9ced..589bfc1 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -2209,6 +2209,13 @@
       },
     },
   },
+  'context_lost_passthrough_tests': {
+    # Not enough capacity.
+    'remove_from': [
+      'Lacros FYI Release (eve)',
+      'Lacros FYI Release (jacuzzi)',
+    ],
+  },
   'context_lost_validating_tests': {
     # TODO(https://crbug.com/850107): Remove the Android FYI Release (Pixel 2)
     # exception once there is enough capacity to run these tests.
@@ -2594,10 +2601,13 @@
     ],
   },
   'gpu_process_launch_tests': {
-    # TODO(https://crbug.com/850107): Remove the Android FYI Release (Pixel 2)
-    # exception once there is enough capacity to run these tests.
     'remove_from': [
+      # TODO(https://crbug.com/850107): Remove the Android FYI Release (Pixel 2)
+      # exception once there is enough capacity to run these tests.
       'Android FYI Release (Pixel 2)',
+      # Not enough capacity.
+      'Lacros FYI Release (eve)',
+      'Lacros FYI Release (jacuzzi)',
     ],
   },
   'gpu_pytype': {
@@ -2623,10 +2633,13 @@
     ],
   },
   'hardware_accelerated_feature_tests': {
-    # TODO(https://crbug.com/850107): Remove the Android FYI Release (Pixel 2)
-    # exception once there is enough capacity to run these tests.
     'remove_from': [
+      # TODO(https://crbug.com/850107): Remove the Android FYI Release (Pixel 2)
+      # exception once there is enough capacity to run these tests.
       'Android FYI Release (Pixel 2)',
+      # Not enough capacity.
+      'Lacros FYI Release (eve)',
+      'Lacros FYI Release (jacuzzi)',
     ],
   },
   'headless_browsertests': {
@@ -3531,6 +3544,11 @@
         ],
       },
     },
+    # Not enough capacity.
+    'remove_from': [
+      'Lacros FYI Release (eve)',
+      'Lacros FYI Release (jacuzzi)',
+    ],
   },
   'screenshot_sync_validating_tests': {
     'modifications': {
@@ -4194,6 +4212,16 @@
           'shards': 30,
         },
       },
+      'Lacros FYI Release (eve)': {
+        'args': [
+          '--test-launcher-filter-file=../../testing/buildbot/filters/lacros-device.webgl2_conformance_gles_passthrough_tests.filter',
+        ],
+      },
+      'Lacros FYI Release (jacuzzi)': {
+        'args': [
+          '--test-launcher-filter-file=../../testing/buildbot/filters/lacros-device.webgl2_conformance_gles_passthrough_tests.filter',
+        ],
+      },
     },
   },
   'webgl2_conformance_metal_passthrough_tests': {
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index 5868cb0..458c6123 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -6805,6 +6805,19 @@
       },
     },
 
+    'gpu_fyi_lacros_device_release_telemetry_tests': {
+      'gpu_passthrough_telemetry_tests': {
+        'variants': [
+          'LACROS_ASH_TOT',
+        ],
+      },
+      'gpu_webgl2_conformance_gles_passthrough_telemetry_tests': {
+        'variants': [
+          'LACROS_ASH_TOT',
+        ],
+      },
+    },
+
     'ios16_beta_simulator_tests': {
       'ios_common_tests': {
         'variants': [
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index 75d3e60..6670906 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_v114.0.5712.0/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5713.0/test_ash_chrome',
     ],
-    'description': 'Run with ash-chrome version 114.0.5712.0',
+    'description': 'Run with ash-chrome version 114.0.5713.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_v114.0.5712.0',
-          'revision': 'version:114.0.5712.0',
+          'location': 'lacros_version_skew_tests_v114.0.5713.0',
+          'revision': 'version:114.0.5713.0',
         },
       ],
     },
@@ -383,8 +383,8 @@
   'CROS_BRYA_RELEASE_LKGM': {
     'skylab': {
       'cros_board': 'brya',
-      'cros_chrome_version': '114.0.5707.0',
-      'cros_img': 'brya-release/R114-15419.0.0',
+      'cros_chrome_version': '114.0.5685.0',
+      'cros_img': 'brya-release/R114-15407.0.0',
       'autotest_name': 'tast.chrome-from-tls',
       'shards': 10,
     },
@@ -394,8 +394,8 @@
   'CROS_DEDEDE_RELEASE_LKGM': {
     'skylab': {
       'cros_board': 'dedede',
-      'cros_chrome_version': '114.0.5707.0',
-      'cros_img': 'dedede-release/R114-15419.0.0',
+      'cros_chrome_version': '114.0.5692.0',
+      'cros_img': 'dedede-release/R114-15410.0.0',
     },
     'enabled': True,
     'identifier': 'DEDEDE_RELEASE_LKGM',
@@ -403,8 +403,8 @@
   'CROS_DEDEDE_RELEASE_DEV': {
     'skylab': {
       'cros_board': 'dedede',
-      'cros_chrome_version': '114.0.5703.0',
-      'cros_img': 'dedede-release/R114-15416.0.0',
+      'cros_chrome_version': '113.0.5672.21',
+      'cros_img': 'dedede-release/R113-15393.12.0',
     },
     'enabled': True,
     'identifier': 'DEDEDE_RELEASE_DEV',
@@ -412,8 +412,8 @@
   'CROS_DEDEDE_RELEASE_BETA': {
     'skylab': {
       'cros_board': 'dedede',
-      'cros_chrome_version': '113.0.5672.21',
-      'cros_img': 'dedede-release/R113-15393.12.0',
+      'cros_chrome_version': '112.0.5615.45',
+      'cros_img': 'dedede-release/R112-15359.37.0',
     },
     'enabled': True,
     'identifier': 'DEDEDE_RELEASE_BETA',
@@ -430,8 +430,8 @@
   'CROS_EVE_RELEASE_LKGM': {
     'skylab': {
       'cros_board': 'eve',
-      'cros_chrome_version': '114.0.5707.0',
-      'cros_img': 'eve-release/R114-15419.0.0',
+      'cros_chrome_version': '114.0.5692.0',
+      'cros_img': 'eve-release/R114-15410.0.0',
     },
     'enabled': True,
     'identifier': 'EVE_RELEASE_LKGM',
@@ -439,8 +439,8 @@
   'CROS_EVE_RELEASE_DEV': {
     'skylab': {
       'cros_board': 'eve',
-      'cros_chrome_version': '114.0.5703.0',
-      'cros_img': 'eve-release/R114-15416.0.0',
+      'cros_chrome_version': '113.0.5672.21',
+      'cros_img': 'eve-release/R113-15393.12.0',
     },
     'enabled': True,
     'identifier': 'EVE_RELEASE_DEV',
@@ -448,8 +448,8 @@
   'CROS_EVE_RELEASE_BETA': {
     'skylab': {
       'cros_board': 'eve',
-      'cros_chrome_version': '113.0.5672.21',
-      'cros_img': 'eve-release/R113-15393.12.0',
+      'cros_chrome_version': '112.0.5615.45',
+      'cros_img': 'eve-release/R112-15359.37.0',
     },
     'enabled': True,
     'identifier': 'EVE_RELEASE_BETA',
@@ -457,8 +457,8 @@
   'CROS_EVE_RELEASE_STABLE': {
     'skylab': {
       'cros_board': 'eve',
-      'cros_chrome_version': '112.0.5615.62',
-      'cros_img': 'eve-release/R112-15359.45.0',
+      'cros_chrome_version': '111.0.5563.118',
+      'cros_img': 'eve-release/R111-15329.59.0',
     },
     'enabled': True,
     'identifier': 'EVE_RELEASE_STABLE',
@@ -466,8 +466,8 @@
   'CROS_EVE_PUBLIC_LKGM': {
     'skylab': {
       'cros_board': 'eve',
-      'cros_chrome_version': '114.0.5707.0',
-      'cros_img': 'eve-public/R114-15419.0.0',
+      'cros_chrome_version': '114.0.5692.0',
+      'cros_img': 'eve-public/R114-15410.0.0',
       'bucket': 'chromiumos-image-archive',
     },
     'enabled': True,
@@ -476,8 +476,8 @@
   'CROS_HANA_RELEASE_LKGM': {
     'skylab': {
       'cros_board': 'hana',
-      'cros_chrome_version': '114.0.5707.0',
-      'cros_img': 'hana-release/R114-15419.0.0',
+      'cros_chrome_version': '114.0.5692.0',
+      'cros_img': 'hana-release/R114-15410.0.0',
     },
     'enabled': True,
     'identifier': 'HANA_RELEASE_LKGM',
@@ -485,8 +485,8 @@
   'CROS_HANA_RELEASE_DEV': {
     'skylab': {
       'cros_board': 'hana',
-      'cros_chrome_version': '114.0.5703.0',
-      'cros_img': 'hana-release/R114-15416.0.0',
+      'cros_chrome_version': '113.0.5672.21',
+      'cros_img': 'hana-release/R113-15393.12.0',
     },
     'enabled': True,
     'identifier': 'HANA_RELEASE_DEV',
@@ -494,8 +494,8 @@
   'CROS_HANA_RELEASE_BETA': {
     'skylab': {
       'cros_board': 'hana',
-      'cros_chrome_version': '113.0.5672.21',
-      'cros_img': 'hana-release/R113-15393.12.0',
+      'cros_chrome_version': '112.0.5615.45',
+      'cros_img': 'hana-release/R112-15359.37.0',
     },
     'enabled': True,
     'identifier': 'HANA_RELEASE_BETA',
@@ -503,8 +503,8 @@
   'CROS_HANA_RELEASE_STABLE': {
     'skylab': {
       'cros_board': 'hana',
-      'cros_chrome_version': '112.0.5615.62',
-      'cros_img': 'hana-release/R112-15359.45.0',
+      'cros_chrome_version': '111.0.5563.118',
+      'cros_img': 'hana-release/R111-15329.59.0',
     },
     'enabled': True,
     'identifier': 'HANA_RELEASE_STABLE',
@@ -512,8 +512,8 @@
   'CROS_HEROBRINE_RELEASE_LKGM': {
     'skylab': {
       'cros_board': 'herobrine',
-      'cros_chrome_version': '114.0.5707.0',
-      'cros_img': 'herobrine-release/R114-15419.0.0',
+      'cros_chrome_version': '114.0.5692.0',
+      'cros_img': 'herobrine-release/R114-15410.0.0',
     },
     'enabled': True,
     'identifier': 'HEROBRINE_RELEASE_LKGM',
@@ -521,8 +521,8 @@
   'CROS_JACUZZI_RELEASE_LKGM': {
     'skylab': {
       'cros_board': 'jacuzzi',
-      'cros_chrome_version': '114.0.5707.0',
-      'cros_img': 'jacuzzi-release/R114-15419.0.0',
+      'cros_chrome_version': '114.0.5692.0',
+      'cros_img': 'jacuzzi-release/R114-15410.0.0',
     },
     'enabled': True,
     'identifier': 'JACUZZI_RELEASE_LKGM',
@@ -530,8 +530,8 @@
   'CROS_JACUZZI_RELEASE_DEV': {
     'skylab': {
       'cros_board': 'jacuzzi',
-      'cros_chrome_version': '114.0.5703.0',
-      'cros_img': 'jacuzzi-release/R114-15416.0.0',
+      'cros_chrome_version': '113.0.5672.21',
+      'cros_img': 'jacuzzi-release/R113-15393.12.0',
     },
     'enabled': True,
     'identifier': 'JACUZZI_RELEASE_DEV',
@@ -539,8 +539,8 @@
   'CROS_JACUZZI_RELEASE_BETA': {
     'skylab': {
       'cros_board': 'jacuzzi',
-      'cros_chrome_version': '113.0.5672.21',
-      'cros_img': 'jacuzzi-release/R113-15393.12.0',
+      'cros_chrome_version': '112.0.5615.45',
+      'cros_img': 'jacuzzi-release/R112-15359.37.0',
     },
     'enabled': True,
     'identifier': 'JACUZZI_RELEASE_BETA',
@@ -560,8 +560,8 @@
   'CROS_JACUZZI_RELEASE_STABLE': {
     'skylab': {
       'cros_board': 'jacuzzi',
-      'cros_chrome_version': '112.0.5615.62',
-      'cros_img': 'jacuzzi-release/R112-15359.45.0',
+      'cros_chrome_version': '111.0.5563.118',
+      'cros_img': 'jacuzzi-release/R111-15329.59.0',
     },
     'enabled': True,
     'identifier': 'JACUZZI_RELEASE_STABLE',
@@ -569,8 +569,8 @@
   'CROS_JACUZZI_PUBLIC_LKGM': {
     'skylab': {
       'cros_board': 'jacuzzi',
-      'cros_chrome_version': '114.0.5707.0',
-      'cros_img': 'jacuzzi-public/R114-15419.0.0',
+      'cros_chrome_version': '114.0.5692.0',
+      'cros_img': 'jacuzzi-public/R114-15410.0.0',
       'bucket': 'chromiumos-image-archive',
     },
     'enabled': True,
@@ -579,8 +579,8 @@
   'CROS_JACUZZI_CQ_PUBLIC_LKGM': {
     'skylab': {
       'cros_board': 'jacuzzi',
-      'cros_chrome_version': '114.0.5707.0',
-      'cros_img': 'jacuzzi-public/R114-15419.0.0',
+      'cros_chrome_version': '114.0.5692.0',
+      'cros_img': 'jacuzzi-public/R114-15410.0.0',
       'bucket': 'chromiumos-image-archive',
       'public_builder': 'cros_test_platform_public',
       'public_builder_bucket': 'testplatform-public',
@@ -591,8 +591,8 @@
   'CROS_KEVIN64_PUBLIC_LKGM': {
     'skylab': {
       'cros_board': 'kevin',
-      'cros_chrome_version': '114.0.5707.0',
-      'cros_img': 'kevin64-public/R114-15419.0.0',
+      'cros_chrome_version': '114.0.5692.0',
+      'cros_img': 'kevin64-public/R114-15410.0.0',
       'bucket': 'chromiumos-image-archive',
     },
     'enabled': True,
@@ -611,8 +611,8 @@
   'CROS_OCTOPUS_PUBLIC_LKGM': {
     'skylab': {
       'cros_board': 'octopus',
-      'cros_chrome_version': '114.0.5707.0',
-      'cros_img': 'octopus-public/R114-15419.0.0',
+      'cros_chrome_version': '114.0.5692.0',
+      'cros_img': 'octopus-public/R114-15410.0.0',
       'bucket': 'chromiumos-image-archive',
     },
     'enabled': True,
@@ -621,8 +621,8 @@
   'CROS_OCTOPUS_RELEASE_CHROME_FROM_TLS_LKGM': {
     'skylab': {
       'cros_board': 'octopus',
-      'cros_chrome_version': '114.0.5707.0',
-      'cros_img': 'octopus-release/R114-15419.0.0',
+      'cros_chrome_version': '114.0.5689.0',
+      'cros_img': 'octopus-release/R114-15408.0.0',
       'tast_expr': '("group:mainline" && !informational)',
       'autotest_name': 'tast.chrome-from-tls',
       'shards': 10,
@@ -633,8 +633,8 @@
   'CROS_OCTOPUS_RELEASE_LKGM': {
     'skylab': {
       'cros_board': 'octopus',
-      'cros_chrome_version': '114.0.5707.0',
-      'cros_img': 'octopus-release/R114-15419.0.0',
+      'cros_chrome_version': '114.0.5692.0',
+      'cros_img': 'octopus-release/R114-15410.0.0',
     },
     'enabled': True,
     'identifier': 'OCTOPUS_RELEASE_LKGM',
@@ -642,8 +642,8 @@
   'CROS_OCTOPUS_RELEASE_DEV': {
     'skylab': {
       'cros_board': 'octopus',
-      'cros_chrome_version': '114.0.5703.0',
-      'cros_img': 'octopus-release/R114-15416.0.0',
+      'cros_chrome_version': '113.0.5672.21',
+      'cros_img': 'octopus-release/R113-15393.12.0',
     },
     'enabled': True,
     'identifier': 'OCTOPUS_RELEASE_DEV',
@@ -651,8 +651,8 @@
   'CROS_OCTOPUS_RELEASE_BETA': {
     'skylab': {
       'cros_board': 'octopus',
-      'cros_chrome_version': '113.0.5672.21',
-      'cros_img': 'octopus-release/R113-15393.12.0',
+      'cros_chrome_version': '112.0.5615.45',
+      'cros_img': 'octopus-release/R112-15359.37.0',
     },
     'enabled': True,
     'identifier': 'OCTOPUS_RELEASE_BETA',
@@ -660,8 +660,8 @@
   'CROS_OCTOPUS_RELEASE_STABLE': {
     'skylab': {
       'cros_board': 'octopus',
-      'cros_chrome_version': '112.0.5615.62',
-      'cros_img': 'octopus-release/R112-15359.45.0',
+      'cros_chrome_version': '111.0.5563.118',
+      'cros_img': 'octopus-release/R111-15329.59.0',
     },
     'enabled': True,
     'identifier': 'OCTOPUS_RELEASE_STABLE',
@@ -669,8 +669,8 @@
   'CROS_STRONGBAD_RELEASE_LKGM': {
     'skylab': {
       'cros_board': 'strongbad',
-      'cros_chrome_version': '114.0.5707.0',
-      'cros_img': 'strongbad-release/R114-15419.0.0',
+      'cros_chrome_version': '114.0.5692.0',
+      'cros_img': 'strongbad-release/R114-15410.0.0',
     },
     'enabled': True,
     'identifier': 'STRONGBAD_RELEASE_LKGM',
@@ -678,8 +678,8 @@
   'CROS_STRONGBAD_RELEASE_DEV': {
     'skylab': {
       'cros_board': 'strongbad',
-      'cros_chrome_version': '114.0.5703.0',
-      'cros_img': 'strongbad-release/R114-15416.0.0',
+      'cros_chrome_version': '113.0.5672.21',
+      'cros_img': 'strongbad-release/R113-15393.12.0',
     },
     'enabled': True,
     'identifier': 'strongbad_RELEASE_DEV',
@@ -687,8 +687,8 @@
   'CROS_STRONGBAD_RELEASE_BETA': {
     'skylab': {
       'cros_board': 'strongbad',
-      'cros_chrome_version': '113.0.5672.21',
-      'cros_img': 'strongbad-release/R113-15393.12.0',
+      'cros_chrome_version': '112.0.5615.45',
+      'cros_img': 'strongbad-release/R112-15359.37.0',
     },
     'enabled': True,
     'identifier': 'STRONGBAD_RELEASE_BETA',
@@ -696,8 +696,8 @@
   'CROS_STRONGBAD_RELEASE_STABLE': {
     'skylab': {
       'cros_board': 'strongbad',
-      'cros_chrome_version': '112.0.5615.62',
-      'cros_img': 'strongbad-release/R112-15359.45.0',
+      'cros_chrome_version': '111.0.5563.118',
+      'cros_img': 'strongbad-release/R111-15329.59.0',
     },
     'enabled': True,
     'identifier': 'STRONGBAD_RELEASE_STABLE',
@@ -705,8 +705,8 @@
   'CROS_TROGDOR_RELEASE_LKGM': {
     'skylab': {
       'cros_board': 'trogdor',
-      'cros_chrome_version': '114.0.5707.0',
-      'cros_img': 'trogdor-release/R114-15419.0.0',
+      'cros_chrome_version': '114.0.5685.0',
+      'cros_img': 'trogdor-release/R114-15407.0.0',
       'autotest_name': 'tast.chrome-from-tls',
       'shards': 10,
     },
@@ -716,8 +716,8 @@
   'CROS_VOLTEER_RELEASE_LKGM': {
     'skylab': {
       'cros_board': 'volteer',
-      'cros_chrome_version': '114.0.5707.0',
-      'cros_img': 'volteer-release/R114-15419.0.0',
+      'cros_chrome_version': '114.0.5685.0',
+      'cros_img': 'volteer-release/R114-15407.0.0',
       'autotest_name': 'tast.chrome-from-tls',
       'shards': 10,
     },
@@ -750,6 +750,12 @@
       ],
     },
   },
+  'LACROS_ASH_TOT': {
+    'args': [
+      '--deploy-lacros',
+    ],
+    'identifier': 'Ash ToT',
+  },
   'LACROS_BETTY_PI_ARC': {
     'args': [
       '--board=betty-pi-arc',
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index bb48f58f..e17f39fbb 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -351,6 +351,49 @@
     },
   },
   {
+    'project': 'chrome',
+    'bucket': 'ci',
+    'name': 'chrome.gpu.fyi',
+    'mixins': [
+      'chrome-tester-service-account',
+      'swarming_containment_auto',
+    ],
+    'machines': {
+      'Lacros FYI Release (eve)': {
+        'additional_compile_targets': [
+          'chrome',
+        ],
+        'os_type': 'chromeos',
+        'browser_config': 'lacros-chrome',
+        'mixins': [
+          'limited_capacity_bot',
+          'chromeos-eve',
+          'chrome-swarming-pool',
+        ],
+        'test_suites': {
+          'gpu_telemetry_tests': 'gpu_fyi_lacros_device_release_telemetry_tests',
+        },
+        'skip_merge_script': True,
+      },
+      'Lacros FYI Release (jacuzzi)': {
+        'additional_compile_targets': [
+          'chrome',
+        ],
+        'os_type': 'chromeos',
+        'browser_config': 'lacros-chrome',
+        'mixins': [
+          'limited_capacity_bot',
+          'chromeos-jacuzzi',
+          'chrome-swarming-pool',
+        ],
+        'test_suites': {
+          'gpu_telemetry_tests': 'gpu_fyi_lacros_device_release_telemetry_tests',
+        },
+        'skip_merge_script': True,
+      },
+    }
+  },
+  {
     'name': 'chromium',
     'mixins': ['chromium-tester-service-account'],
     'machines': {
diff --git a/testing/chromoting/OWNERS b/testing/chromoting/OWNERS
index 989a265..79df492 100644
--- a/testing/chromoting/OWNERS
+++ b/testing/chromoting/OWNERS
@@ -1,3 +1,2 @@
 jamiewalch@chromium.org
 joedow@chromium.org
-sergeyu@chromium.org
diff --git a/testing/platform_test.h b/testing/platform_test.h
index 80f9cc8d..f14bd454 100644
--- a/testing/platform_test.h
+++ b/testing/platform_test.h
@@ -8,11 +8,9 @@
 #include <gtest/gtest.h>
 
 #if defined(GTEST_OS_MAC)
-#include <objc/objc.h>
-
 // The purpose of this class us to provide a hook for platform-specific
 // operations across unit tests.  For example, on the Mac, it creates and
-// releases an outer NSAutoreleasePool for each test case.  For now, it's only
+// releases an autorelease pool for each test case.  For now, it's only
 // implemented on the Mac.  To enable this for another platform, just adjust
 // the #ifdefs and add a platform_test_<platform>.cc implementation file.
 class PlatformTest : public testing::Test {
@@ -23,13 +21,12 @@
   PlatformTest();
 
  private:
-  // |pool_| is a NSAutoreleasePool, but since this header may be imported from
-  // files built with Objective-C ARC that forbids explicit usage of
-  // NSAutoreleasePools, it is declared as id here.
-  id pool_;
+  void* autorelease_pool_;
 };
 #else
-typedef testing::Test PlatformTest;
+
+using PlatformTest = testing::Test;
+
 #endif // GTEST_OS_MAC
 
 #endif // TESTING_PLATFORM_TEST_H_
diff --git a/testing/platform_test_mac.mm b/testing/platform_test_mac.mm
index 30126fc..d52ad37 100644
--- a/testing/platform_test_mac.mm
+++ b/testing/platform_test_mac.mm
@@ -4,12 +4,17 @@
 
 #include "platform_test.h"
 
-#import <Foundation/Foundation.h>
+// Note that this uses the direct runtime interface to the autorelease pool.
+// https://clang.llvm.org/docs/AutomaticReferenceCounting.html#runtime-support
+// This is so this can work when compiled for ARC.
 
-PlatformTest::PlatformTest()
-    : pool_([[NSAutoreleasePool alloc] init]) {
+extern "C" {
+void* objc_autoreleasePoolPush(void);
+void objc_autoreleasePoolPop(void* pool);
 }
 
+PlatformTest::PlatformTest() : autorelease_pool_(objc_autoreleasePoolPush()) {}
+
 PlatformTest::~PlatformTest() {
-  [pool_ release];
+  objc_autoreleasePoolPop(autorelease_pool_);
 }
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 2f0fff1..9bf9391 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -211,6 +211,35 @@
             ]
         }
     ],
+    "AndroidMediaPickerAdoption": [
+        {
+            "platforms": [
+                "android"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled_Direct",
+                    "params": {
+                        "use_action_pick_images": "true"
+                    },
+                    "enable_features": [
+                        "MediaPickerAdoption"
+                    ],
+                    "min_os_version": "13.0.0"
+                },
+                {
+                    "name": "Enabled_Direct_Plus",
+                    "params": {
+                        "use_action_pick_images_plus": "true"
+                    },
+                    "enable_features": [
+                        "MediaPickerAdoption"
+                    ],
+                    "min_os_version": "13.0.0"
+                }
+            ]
+        }
+    ],
     "AndroidMessagesSaveCard": [
         {
             "platforms": [
@@ -2006,6 +2035,21 @@
             ]
         }
     ],
+    "CALayerNewLimit": [
+        {
+            "platforms": [
+                "mac"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "CALayerNewLimit"
+                    ]
+                }
+            ]
+        }
+    ],
     "CPSS": [
         {
             "platforms": [
@@ -5091,22 +5135,6 @@
             ]
         }
     ],
-    "FastPairPowerConsumption": [
-        {
-            "platforms": [
-                "chromeos"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled_20220919",
-                    "enable_features": [
-                        "FastPair",
-                        "FastPairSavedDevices"
-                    ]
-                }
-            ]
-        }
-    ],
     "FastPathPaintPropertyUpdates": [
         {
             "platforms": [
@@ -9821,9 +9849,7 @@
                         "IPH_PerformanceNewBadge",
                         "PageTimelineMonitor"
                     ],
-                    "disable_features": [
-                        "IPH_HighEfficiencyInfoMode"
-                    ]
+                    "disable_features": []
                 }
             ]
         }
@@ -14064,21 +14090,6 @@
             ]
         }
     ],
-    "WebApkManifestUniqueId": [
-        {
-            "platforms": [
-                "android"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "WebApkUniqueId"
-                    ]
-                }
-            ]
-        }
-    ],
     "WebAuthFlowInBrowserTab": [
         {
             "platforms": [
diff --git a/third_party/blink/common/switches.cc b/third_party/blink/common/switches.cc
index 75deec5..1700b28 100644
--- a/third_party/blink/common/switches.cc
+++ b/third_party/blink/common/switches.cc
@@ -118,9 +118,6 @@
 // signal to dismiss a splash screen.
 const char kNetworkQuietTimeout[] = "network-quiet-timeout";
 
-// Number of worker threads used to rasterize content.
-const char kNumRasterThreads[] = "num-raster-threads";
-
 // Visibly render a border around layout shift rects in the web page to help
 // debug and study layout shifts.
 const char kShowLayoutShiftRegions[] = "show-layout-shift-regions";
diff --git a/third_party/blink/public/common/switches.h b/third_party/blink/public/common/switches.h
index d70c831a..26945c1f 100644
--- a/third_party/blink/public/common/switches.h
+++ b/third_party/blink/public/common/switches.h
@@ -62,7 +62,6 @@
 BLINK_COMMON_EXPORT extern const char kMaxUntiledLayerWidth[];
 BLINK_COMMON_EXPORT extern const char kMinHeightForGpuRasterTile[];
 BLINK_COMMON_EXPORT extern const char kNetworkQuietTimeout[];
-BLINK_COMMON_EXPORT extern const char kNumRasterThreads[];
 BLINK_COMMON_EXPORT extern const char kSharedArrayBufferAllowedOrigins[];
 BLINK_COMMON_EXPORT extern const char kShowLayoutShiftRegions[];
 BLINK_COMMON_EXPORT extern const char kShowPaintRects[];
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
index cfe1148..1d34dbd 100644
--- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl
+++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -775,6 +775,15 @@
       # One of the deprecation names from third_party/blink/renderer/core/frame/deprecation/deprecation.json5
       string type
 
+  # This issue warns about sites in the redirect chain of a finished navigation
+  # that may be flagged as trackers and have their state cleared if they don't
+  # receive a user interaction. Note that in this context 'site' means eTLD+1. 
+  # For example, if the URL `https://example.test:80/bounce` was in the 
+  # redirect chain, the site reported would be `example.test`.
+  type BounceTrackingIssueDetails extends object
+    properties
+      array of string trackingSites
+
   type ClientHintIssueReason extends string
     enum
       # Items in the accept-ch meta tag allow list must be valid origins.
@@ -851,6 +860,7 @@
       DeprecationIssue
       ClientHintIssue
       FederatedAuthRequestIssue
+      BounceTrackingIssue
 
   # This struct holds a list of optional fields with additional information
   # specific to the kind of issue. When adding a new issue code, please also
@@ -873,6 +883,7 @@
       optional DeprecationIssueDetails deprecationIssueDetails
       optional ClientHintIssueDetails clientHintIssueDetails
       optional FederatedAuthRequestIssueDetails federatedAuthRequestIssueDetails
+      optional BounceTrackingIssueDetails bounceTrackingIssueDetails
 
   # A unique id for a DevTools inspector issue. Allows other entities (e.g.
   # exceptions, CDP message, console messages, etc.) to reference an issue.
diff --git a/third_party/blink/public/mojom/devtools/inspector_issue.mojom b/third_party/blink/public/mojom/devtools/inspector_issue.mojom
index 4fde945..535428a 100644
--- a/third_party/blink/public/mojom/devtools/inspector_issue.mojom
+++ b/third_party/blink/public/mojom/devtools/inspector_issue.mojom
@@ -22,6 +22,7 @@
   kHeavyAdIssue,
   kLowTextContrastIssue,
   kFederatedAuthRequestIssue,
+  kBounceTrackingIssue,
   kGenericIssue,
   kDeprecationIssue,
 };
@@ -220,6 +221,10 @@
   FederatedAuthRequestResult status;
 };
 
+struct BounceTrackingIssueDetails {
+  array<string> tracking_sites;
+};
+
 enum GenericIssueErrorType {
   kCrossOriginPortalPostMessageError,
   kFormLabelForNameError,
@@ -263,6 +268,7 @@
   HeavyAdIssueDetails? heavy_ad_issue_details;
   LowTextContrastIssue? low_text_contrast_details;
   FederatedAuthRequestIssueDetails? federated_auth_request_details;
+  BounceTrackingIssueDetails? bounce_tracking_issue_details;
   GenericIssueDetails? generic_issue_details;
   DeprecationIssueDetails? deprecation_issue_details;
   mojo_base.mojom.UnguessableToken? issue_id;
diff --git a/third_party/blink/public/mojom/webauthn/authenticator.mojom b/third_party/blink/public/mojom/webauthn/authenticator.mojom
index 5367034..04e72eb8 100644
--- a/third_party/blink/public/mojom/webauthn/authenticator.mojom
+++ b/third_party/blink/public/mojom/webauthn/authenticator.mojom
@@ -281,16 +281,6 @@
   array<uint8>? experiments;
 };
 
-// Cloud-assisted BLE extension data for makeCredential.
-struct CableRegistration {
-  // The caBLE versions supported by the relying party.
-  array<uint8> versions;
-
-  // The 65-byte ECDSA ephemeral public key belonging to the relying party
-  // for use in establishing an encrypted caBLE channel with an authenticator.
-  array<uint8, 65> relying_party_public_key;
-};
-
 // See https://w3c.github.io/webauthn/#dictdef-authenticationextensionsprfvalues
 struct PRFValues {
   // In the Javascript-to-native direction, id is the credential ID for these
@@ -485,12 +475,6 @@
   // credential.
   AttestationConveyancePreference attestation;
 
-  // The contents of the cloud assisted BLE extension for makeCredential
-  // requests, if any. This extension permits browsers and authenticator
-  // devices to establish a pairingless BLE connection.
-  // TODO(crbug.com/842371): Add link to spec when available.
-  CableRegistration? cable_registration_data;
-
   // The contents of the hmacCreateSecret extension, if any. See
   // https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-client-to-authenticator-protocol-v2.0-rd-20180702.html#sctn-hmac-secret-extension
   bool hmac_create_secret;
diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni
index bcd6a715..0bdb4488e 100644
--- a/third_party/blink/renderer/bindings/generated_in_modules.gni
+++ b/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -237,8 +237,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_browsing_topics_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cable_authentication_data.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cable_authentication_data.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cable_registration_data.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cable_registration_data.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cache_query_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cache_query_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_camera_device_permission_descriptor.cc",
diff --git a/third_party/blink/renderer/bindings/idl_in_modules.gni b/third_party/blink/renderer/bindings/idl_in_modules.gni
index c515555..894451f8 100644
--- a/third_party/blink/renderer/bindings/idl_in_modules.gni
+++ b/third_party/blink/renderer/bindings/idl_in_modules.gni
@@ -151,7 +151,6 @@
           "//third_party/blink/renderer/modules/credentialmanagement/authenticator_response.idl",
           "//third_party/blink/renderer/modules/credentialmanagement/authenticator_selection_criteria.idl",
           "//third_party/blink/renderer/modules/credentialmanagement/cable_authentication_data.idl",
-          "//third_party/blink/renderer/modules/credentialmanagement/cable_registration_data.idl",
           "//third_party/blink/renderer/modules/credentialmanagement/collected_client_data.idl",
           "//third_party/blink/renderer/modules/credentialmanagement/credential.idl",
           "//third_party/blink/renderer/modules/credentialmanagement/credential_creation_options.idl",
diff --git a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
index a99952f..3db51e1a 100644
--- a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
@@ -75,6 +75,7 @@
 #include "third_party/blink/renderer/platform/widget/frame_widget.h"
 
 #if BUILDFLAG(IS_MAC)
+#include "base/mac/foundation_util.h"
 #include "third_party/blink/renderer/core/editing/substring_util.h"
 #include "third_party/blink/renderer/platform/fonts/mac/attributed_string_type_converter.h"
 #include "ui/base/mojom/attributed_string.mojom-blink.h"
@@ -1007,8 +1008,10 @@
   NSAttributedString* string = SubstringUtil::AttributedSubstringInRange(
       frame_, base::checked_cast<WTF::wtf_size_t>(range.start()),
       base::checked_cast<WTF::wtf_size_t>(range.length()), baseline_point);
-  if (string)
-    attributed_string = ui::mojom::blink::AttributedString::From(string);
+  if (string) {
+    attributed_string =
+        ui::mojom::blink::AttributedString::From(base::mac::NSToCFCast(string));
+  }
 
   std::move(callback).Run(std::move(attributed_string), baseline_point);
 }
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
index 9bd1f83..01b1cb9 100644
--- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
@@ -149,6 +149,7 @@
 #include "ui/gfx/geometry/point_conversions.h"
 
 #if BUILDFLAG(IS_MAC)
+#include "base/mac/foundation_util.h"
 #include "third_party/blink/renderer/core/editing/substring_util.h"
 #include "third_party/blink/renderer/platform/fonts/mac/attributed_string_type_converter.h"
 #include "ui/base/mojom/attributed_string.mojom-blink.h"
@@ -661,8 +662,10 @@
   ui::mojom::blink::AttributedStringPtr attributed_string = nullptr;
   NSAttributedString* string = SubstringUtil::AttributedWordAtPoint(
       this, point_in_local_root, baseline_point);
-  if (string)
-    attributed_string = ui::mojom::blink::AttributedString::From(string);
+  if (string) {
+    attributed_string =
+        ui::mojom::blink::AttributedString::From(base::mac::NSToCFCast(string));
+  }
 
   std::move(callback).Run(std::move(attributed_string), baseline_point);
 }
diff --git a/third_party/blink/renderer/core/input/event_handler.cc b/third_party/blink/renderer/core/input/event_handler.cc
index df8f440..04b6eb7 100644
--- a/third_party/blink/renderer/core/input/event_handler.cc
+++ b/third_party/blink/renderer/core/input/event_handler.cc
@@ -188,12 +188,6 @@
 // when intersecting browser native UI.
 static const int kMaximumCursorSizeWithoutFallback = 32;
 
-// It's pretty unlikely that a scale of less than one would ever be used. But
-// all we really need to ensure here is that the scale isn't so small that
-// integer overflow can occur when dividing cursor sizes (limited above) by the
-// scale.
-static const double kMinimumCursorScale = 0.001;
-
 // The minimum amount of time an element stays active after a ShowPress
 // This is roughly 9 frames, which should be long enough to be noticeable.
 constexpr base::TimeDelta kMinimumActiveInterval = base::Seconds(0.15);
@@ -584,22 +578,14 @@
                                  kRespectImageOrientation);
 
       Image* image = cached_image->GetImage();
-
-      // If the image is an SVG, then adjust the scale to reflect the device
-      // scale factor so that the SVG can be rasterized in the native
-      // resolution and scaled down to the correct size for the cursor.
-      float device_scale_factor = 1;
       if (image->IsSVGImage()) {
-        // Limit the size of cursors (in DIP) so that they cannot be
-        // used to cover UI elements in chrome. StyleImage::ImageSize does not
-        // take StyleImage::ImageScaleFactor() into account when computing the
-        // size for SVG images.
+        // `StyleImage::ImageSize` does not take `StyleImage::ImageScaleFactor`
+        // into account when computing the size for SVG images.
         size.Scale(1 / scale);
-        device_scale_factor =
-            page->GetChromeClient().GetScreenInfo(*frame_).device_scale_factor;
-        scale *= device_scale_factor;
       }
 
+      // Limit the size of cursors (in DIP) so that they cannot be used to cover
+      // UI elements in chrome.
       if (size.IsEmpty() || size.width() > kMaximumCursorSize ||
           size.height() > kMaximumCursorSize)
         continue;
@@ -630,19 +616,17 @@
         }
       }
 
-      // Ensure no overflow possible in calculations above.
-      if (scale < kMinimumCursorScale)
-        continue;
-
-      // Convert from DIP to physical pixels.
-      hot_spot = gfx::ScaleToRoundedPoint(hot_spot, scale);
-
-      // Special case for SVG so that it can be rasterized in the appropriate
-      // resolution for high DPI displays.
+      // If the image is an SVG, then adjust the scale to reflect the device
+      // scale factor so that the SVG can be rasterized in the native
+      // resolution and scaled down to the correct size for the cursor.
       scoped_refptr<Image> svg_image_holder;
       if (auto* svg_image = DynamicTo<SVGImage>(image)) {
+        const float device_scale_factor =
+            page->GetChromeClient().GetScreenInfo(*frame_).device_scale_factor;
+        scale *= device_scale_factor;
         // Re-scale back from DIP to device pixels.
         size.Scale(scale);
+
         // TODO(fs): Should pass proper URL. Use StyleImage::GetImage.
         svg_image_holder = SVGImageForContainer::Create(
             svg_image, size, device_scale_factor, NullURL(),
@@ -652,6 +636,9 @@
         image = svg_image_holder.get();
       }
 
+      // Convert from DIP to physical pixels.
+      hot_spot = gfx::ScaleToRoundedPoint(hot_spot, scale);
+
       return ui::Cursor::NewCustom(
           image->AsSkBitmapForCurrentFrame(kRespectImageOrientation),
           DetermineHotSpot(*image, hot_spot_specified, hot_spot), scale);
diff --git a/third_party/blink/renderer/core/inspector/inspector_issue_conversion.cc b/third_party/blink/renderer/core/inspector/inspector_issue_conversion.cc
index c5c3fc2..d5dd4b0 100644
--- a/third_party/blink/renderer/core/inspector/inspector_issue_conversion.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_issue_conversion.cc
@@ -64,6 +64,8 @@
     case mojom::blink::InspectorIssueCode::kFederatedAuthRequestIssue:
       CHECK(false);
       return "";
+    case mojom::blink::InspectorIssueCode::kBounceTrackingIssue:
+      NOTREACHED_NORETURN();
     case mojom::blink::InspectorIssueCode::kGenericIssue:
       NOTREACHED();
       return "";
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
index 25c1af4..da59c962 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -132,8 +132,6 @@
       layer_(&layer),
       in_resize_mode_(false),
       scrolls_overflow_(false),
-      in_overflow_relayout_(false),
-      allow_second_overflow_relayout_(false),
       needs_composited_scrolling_(false),
       needs_scroll_offset_clamp_(false),
       needs_relayout_(false),
@@ -964,15 +962,8 @@
 void PaintLayerScrollableArea::UpdateAfterLayout() {
   InvalidateAllStickyConstraints();
 
-  bool is_horizontal_scrollbar_frozen;
-  bool is_vertical_scrollbar_frozen;
-  if (in_overflow_relayout_ && !allow_second_overflow_relayout_) {
-    is_horizontal_scrollbar_frozen = is_vertical_scrollbar_frozen = true;
-  } else {
-    is_horizontal_scrollbar_frozen = IsHorizontalScrollbarFrozen();
-    is_vertical_scrollbar_frozen = IsVerticalScrollbarFrozen();
-  }
-  allow_second_overflow_relayout_ = false;
+  bool is_horizontal_scrollbar_frozen = IsHorizontalScrollbarFrozen();
+  bool is_vertical_scrollbar_frozen = IsVerticalScrollbarFrozen();
 
   if (NeedsScrollbarReconstruction()) {
     RemoveScrollbarsForReconstruction();
@@ -995,16 +986,10 @@
   ComputeScrollbarExistence(kLayout, needs_horizontal_scrollbar,
                             needs_vertical_scrollbar);
 
-  // Removing auto scrollbars is a heuristic and can be incorrect if the content
-  // size depends on the scrollbar size (e.g., sized with percentages). Removing
-  // scrollbars can require two additional layout passes so this is only done on
-  // the first layout (!in_overflow_layout).
-  if (!in_overflow_relayout_ && !is_horizontal_scrollbar_frozen &&
-      !is_vertical_scrollbar_frozen &&
+  if (!is_horizontal_scrollbar_frozen && !is_vertical_scrollbar_frozen &&
       TryRemovingAutoScrollbars(needs_horizontal_scrollbar,
                                 needs_vertical_scrollbar)) {
     needs_horizontal_scrollbar = needs_vertical_scrollbar = false;
-    allow_second_overflow_relayout_ = true;
   }
 
   bool horizontal_scrollbar_should_change =
@@ -1050,25 +1035,10 @@
            !GetLayoutBox()->IsHorizontalWritingMode())) {
         GetLayoutBox()->SetIntrinsicLogicalWidthsDirty();
       }
-      if (IsManagedByLayoutNG(*GetLayoutBox())) {
-        // If the box is managed by LayoutNG, don't go here. We don't want to
-        // re-enter the NG layout algorithm for this box from here. Just update
-        // the rectangles, in case scrollbars were added or removed. LayoutNG
-        // has its own scrollbar change detection mechanism.
-        UpdateScrollDimensions();
-      } else {
-        in_overflow_relayout_ = true;
-        SubtreeLayoutScope layout_scope(*GetLayoutBox());
-        layout_scope.SetNeedsLayout(
-            GetLayoutBox(), layout_invalidation_reason::kScrollbarChanged);
-        if (auto* block = DynamicTo<LayoutBlock>(GetLayoutBox())) {
-          block->UpdateBlockLayout(true);
-        } else {
-          GetLayoutBox()->UpdateLayout();
-        }
-        in_overflow_relayout_ = false;
-        scrollbar_manager_.DestroyDetachedScrollbars();
-      }
+      // Just update the rectangles, in case scrollbars were added or
+      // removed. The calling code on the layout side has its own scrollbar
+      // change detection mechanism.
+      UpdateScrollDimensions();
     }
   } else if (!HasScrollbar() && resizer_will_change) {
     Layer()->DirtyStackingContextZOrderLists();
@@ -1651,11 +1621,6 @@
 bool PaintLayerScrollableArea::TryRemovingAutoScrollbars(
     const bool& needs_horizontal_scrollbar,
     const bool& needs_vertical_scrollbar) {
-  // If scrollbars are removed but the content size depends on the scrollbars,
-  // additional layouts will be required to size the content. Therefore, only
-  // remove auto scrollbars for the initial layout pass.
-  DCHECK(!in_overflow_relayout_);
-
   if (!needs_horizontal_scrollbar && !needs_vertical_scrollbar)
     return false;
 
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
index 62c40622..9f95065 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
+++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
@@ -727,12 +727,6 @@
   unsigned in_resize_mode_ : 1;
   unsigned scrolls_overflow_ : 1;
 
-  // True if we are in an overflow scrollbar relayout.
-  unsigned in_overflow_relayout_ : 1;
-
-  // True if a second overflow scrollbar relayout is permitted.
-  unsigned allow_second_overflow_relayout_ : 1;
-
   // FIXME: once cc can handle composited scrolling with clip paths, we will
   // no longer need this bit.
   unsigned needs_composited_scrolling_ : 1;
diff --git a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc
index 2ad38389..25a7934 100644
--- a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc
+++ b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc
@@ -455,10 +455,19 @@
   // If we're in a fragmentation context, the parent fragment of OOFs is the
   // fragmentainer, unless the object is monolithic, in which case nothing
   // contained by the object participates in the current block fragmentation
-  // context. If we're not participating in block fragmentation, the containing
-  // fragment of an OOF fragment is always simply the parent.
+  // context. The monolithic-check here is somewhat special, to match the
+  // behavior in OOF layout. We need to check that we're monolithic AND the
+  // first fragment of the node in order to act as an OOF container. A non-first
+  // fragment may be set as monolithic if overflow is clipped and we've reached
+  // the end right there. But that doesn't affect how OOF layout behaves. In
+  // such cases, where there's more than one fragment involved, an OOF fragment
+  // will become a direct child of a fragmentainer, just as if there were no
+  // monolithicness involved at all.
+  //
+  // If we're not participating in block fragmentation, the containing fragment
+  // of an OOF fragment is always simply the parent.
   if (!context.current_container.IsInFragmentationContext() ||
-      (fragment && fragment->IsMonolithic())) {
+      (fragment && fragment->IsMonolithic() && fragment->IsFirstForNode())) {
     // Anonymous blocks are not allowed to be containing blocks, so we should
     // skip over any such elements.
     if (!fragment || !fragment->IsAnonymousBlock()) {
diff --git a/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc b/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc
index 3f766ac..e429205 100644
--- a/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc
+++ b/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc
@@ -520,10 +520,6 @@
   if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
     return;
 
-  // Hack around libxml2's lack of encoding overide support by manually
-  // resetting the encoding to UTF-16 before every chunk. Otherwise libxml
-  // will detect <?xml version="1.0" encoding="<encoding name>"?> blocks and
-  // switch encodings, causing the parse to fail.
   if (is_8bit) {
     xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_8859_1);
     return;
@@ -538,6 +534,7 @@
 
 static void ParseChunk(xmlParserCtxtPtr ctxt, const String& chunk) {
   bool is_8bit = chunk.Is8Bit();
+  // Reset the encoding for each chunk to reflect if it is Latin-1 or UTF-16.
   SwitchEncoding(ctxt, is_8bit);
   if (is_8bit)
     xmlParseChunk(ctxt, reinterpret_cast<const char*>(chunk.Characters8()),
@@ -1500,6 +1497,11 @@
 static void StartDocumentHandler(void* closure) {
   xmlParserCtxt* ctxt = static_cast<xmlParserCtxt*>(closure);
   XMLDocumentParser* parser = GetParser(closure);
+  // Reset the encoding back to match that of the current data block (Latin-1 /
+  // UTF-16), since libxml may switch encoding based on the XML declaration -
+  // which it has now seen - causing the parse to fail. We could use the
+  // XML_PARSE_IGNORE_ENC option to avoid this, but we're relying on populating
+  // the 'xmlEncoding' property with the value it yields.
   SwitchEncoding(ctxt, parser->IsCurrentlyParsing8BitChunk());
   parser->StartDocument(ToString(ctxt->version), ToString(ctxt->encoding),
                         ctxt->standalone);
diff --git a/third_party/blink/renderer/modules/BUILD.gn b/third_party/blink/renderer/modules/BUILD.gn
index 6df1e86..0799581 100644
--- a/third_party/blink/renderer/modules/BUILD.gn
+++ b/third_party/blink/renderer/modules/BUILD.gn
@@ -184,6 +184,7 @@
 
   deps = [
     ":make_modules_generated",
+    "//cc",
     "//components/webrtc:thread_wrapper",
     "//gin",
     "//net:net",
diff --git a/third_party/blink/renderer/modules/DEPS b/third_party/blink/renderer/modules/DEPS
index aa82aa38..49b549c 100644
--- a/third_party/blink/renderer/modules/DEPS
+++ b/third_party/blink/renderer/modules/DEPS
@@ -36,6 +36,9 @@
         "+testing/libfuzzer/proto/lpm_interface.h",
         "+third_party/protobuf/src/google/protobuf/repeated_field.h",
     ],
+    "modules_initializer.cc": [
+        "+cc/raster/categorized_worker_pool.h",
+    ],
     ".*_decoder_fuzzer.cc": [
         "+base/run_loop.h",
     ],
diff --git a/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_client_inputs.idl b/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_client_inputs.idl
index e10e0ce0..7bdc2b9 100644
--- a/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_client_inputs.idl
+++ b/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_client_inputs.idl
@@ -10,7 +10,6 @@
 
   // https://w3c.github.io/webauthn/#sctn-appid-exclude-extension
   USVString appidExclude;
-  CableRegistrationData cableRegistration;
   sequence<CableAuthenticationData> cableAuthentication;
 
   // https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-client-to-authenticator-protocol-v2.0-rd-20180702.html#sctn-hmac-secret-extension
diff --git a/third_party/blink/renderer/modules/credentialmanagement/cable_registration_data.idl b/third_party/blink/renderer/modules/credentialmanagement/cable_registration_data.idl
deleted file mode 100644
index fd950cb..0000000
--- a/third_party/blink/renderer/modules/credentialmanagement/cable_registration_data.idl
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2018 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-dictionary CableRegistrationData {
-  required sequence<octet> versions;
-  required BufferSource rpPublicKey;
-};
diff --git a/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.cc b/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.cc
index 9ad9be4..a98efc3 100644
--- a/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.cc
+++ b/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.cc
@@ -21,7 +21,6 @@
 #include "third_party/blink/renderer/bindings/modules/v8/v8_authentication_extensions_prf_values.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_authenticator_selection_criteria.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_cable_authentication_data.h"
-#include "third_party/blink/renderer/bindings/modules/v8/v8_cable_registration_data.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_identity_credential_logout_r_ps_request.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_identity_credential_request_options_context.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_identity_provider_config.h"
@@ -53,8 +52,6 @@
 using blink::mojom::blink::AuthenticatorTransport;
 using blink::mojom::blink::CableAuthentication;
 using blink::mojom::blink::CableAuthenticationPtr;
-using blink::mojom::blink::CableRegistration;
-using blink::mojom::blink::CableRegistrationPtr;
 using blink::mojom::blink::CredentialInfo;
 using blink::mojom::blink::CredentialInfoPtr;
 using blink::mojom::blink::CredentialType;
@@ -532,13 +529,6 @@
     if (extensions->hasAppidExclude()) {
       mojo_options->appid_exclude = extensions->appidExclude();
     }
-    if (extensions->hasCableRegistration()) {
-      CableRegistrationPtr mojo_cable =
-          CableRegistration::From(*extensions->cableRegistration());
-      if (mojo_cable) {
-        mojo_options->cable_registration_data = std::move(mojo_cable);
-      }
-    }
     if (extensions->hasHmacCreateSecret()) {
       mojo_options->hmac_create_secret = extensions->hmacCreateSecret();
     }
@@ -633,20 +623,6 @@
 }
 
 // static
-CableRegistrationPtr
-TypeConverter<CableRegistrationPtr, blink::CableRegistrationData>::Convert(
-    const blink::CableRegistrationData& data) {
-  auto entity = CableRegistration::New();
-  entity->versions = data.versions();
-  entity->relying_party_public_key =
-      ConvertFixedSizeArray(data.rpPublicKey(), 65);
-  if (entity->relying_party_public_key.empty()) {
-    return nullptr;
-  }
-  return entity;
-}
-
-// static
 PublicKeyCredentialRequestOptionsPtr
 TypeConverter<PublicKeyCredentialRequestOptionsPtr,
               blink::PublicKeyCredentialRequestOptions>::
diff --git a/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.h b/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.h
index c715ecd..b8ddb23 100644
--- a/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.h
+++ b/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.h
@@ -21,7 +21,6 @@
 class AuthenticationExtensionsPRFValues;
 class AuthenticatorSelectionCriteria;
 class CableAuthenticationData;
-class CableRegistrationData;
 class Credential;
 class IdentityCredentialLogoutRPsRequest;
 class IdentityProviderConfig;
@@ -177,13 +176,6 @@
 };
 
 template <>
-struct TypeConverter<blink::mojom::blink::CableRegistrationPtr,
-                     blink::CableRegistrationData> {
-  static blink::mojom::blink::CableRegistrationPtr Convert(
-      const blink::CableRegistrationData&);
-};
-
-template <>
 struct TypeConverter<blink::mojom::blink::PublicKeyCredentialRequestOptionsPtr,
                      blink::PublicKeyCredentialRequestOptions> {
   static blink::mojom::blink::PublicKeyCredentialRequestOptionsPtr Convert(
diff --git a/third_party/blink/renderer/modules/credentialmanagement/credentials_container.cc b/third_party/blink/renderer/modules/credentialmanagement/credentials_container.cc
index 13f165db..7569719f 100644
--- a/third_party/blink/renderer/modules/credentialmanagement/credentials_container.cc
+++ b/third_party/blink/renderer/modules/credentialmanagement/credentials_container.cc
@@ -1191,13 +1191,6 @@
           }
         }
       }
-      if (options->publicKey()->extensions()->hasCableRegistration()) {
-        resolver->Reject(MakeGarbageCollected<DOMException>(
-            DOMExceptionCode::kNotSupportedError,
-            "The 'cableRegistration' extension is only valid when creating "
-            "a credential"));
-        return promise;
-      }
       if (options->publicKey()->extensions()->credProps()) {
         resolver->Reject(MakeGarbageCollected<DOMException>(
             DOMExceptionCode::kNotSupportedError,
diff --git a/third_party/blink/renderer/modules/modules_initializer.cc b/third_party/blink/renderer/modules/modules_initializer.cc
index 8d72cfd..1c68797 100644
--- a/third_party/blink/renderer/modules/modules_initializer.cc
+++ b/third_party/blink/renderer/modules/modules_initializer.cc
@@ -9,6 +9,7 @@
 #include "base/memory/ptr_util.h"
 #include "base/task/thread_pool.h"
 #include "build/build_config.h"
+#include "cc/raster/categorized_worker_pool.h"
 #include "mojo/public/cpp/bindings/binder_map.h"
 #include "third_party/blink/public/mojom/dom_storage/session_storage_namespace.mojom-blink.h"
 #include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h"
@@ -103,7 +104,7 @@
 #include "third_party/blink/renderer/platform/heap/persistent.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
-#include "third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool.h"
+#include "third_party/blink/renderer/platform/widget/compositing/blink_categorized_worker_pool_delegate.h"
 #include "third_party/blink/renderer/platform/widget/frame_widget.h"
 #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -343,7 +344,8 @@
       frame_widget->GetLayerTreeSettings(),
       base::FeatureList::IsEnabled(kBlinkMediaPlayerUsesBaseThreadPool)
           ? base::ThreadPool::CreateTaskRunner(base::TaskTraits{})
-          : CategorizedWorkerPool::GetOrCreate()));
+          : cc::CategorizedWorkerPool::GetOrCreate(
+                &BlinkCategorizedWorkerPoolDelegate::Get())));
 }
 
 WebRemotePlaybackClient* ModulesInitializer::CreateWebRemotePlaybackClient(
diff --git a/third_party/blink/renderer/modules/shared_storage/window_shared_storage.idl b/third_party/blink/renderer/modules/shared_storage/window_shared_storage.idl
index 5eb091b4..32c6d45d 100644
--- a/third_party/blink/renderer/modules/shared_storage/window_shared_storage.idl
+++ b/third_party/blink/renderer/modules/shared_storage/window_shared_storage.idl
@@ -2,5 +2,8 @@
   RuntimeEnabled=SharedStorageAPI,
   ImplementedAs=WindowSharedStorage
 ] partial interface Window {
-  [MeasureAs=SharedStorageAPI_SharedStorage_DOMReference] readonly attribute SharedStorage sharedStorage;
+  [
+    MeasureAs=SharedStorageAPI_SharedStorage_DOMReference,
+    SecureContext
+  ] readonly attribute SharedStorage sharedStorage;
 };
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn
index 2fb2134..3473589 100644
--- a/third_party/blink/renderer/platform/BUILD.gn
+++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -1505,8 +1505,8 @@
     "webrtc/webrtc_video_frame_adapter.h",
     "webrtc/webrtc_video_utils.cc",
     "webrtc/webrtc_video_utils.h",
-    "widget/compositing/categorized_worker_pool.cc",
-    "widget/compositing/categorized_worker_pool.h",
+    "widget/compositing/blink_categorized_worker_pool_delegate.cc",
+    "widget/compositing/blink_categorized_worker_pool_delegate.h",
     "widget/compositing/layer_tree_settings.cc",
     "widget/compositing/layer_tree_settings.h",
     "widget/compositing/layer_tree_view.cc",
@@ -1684,6 +1684,7 @@
     "//base/allocator:buildflags",
     "//build:chromecast_buildflags",
     "//build:chromeos_buildflags",
+    "//cc",
     "//cc/ipc",
     "//cc/mojo_embedder",
     "//components/paint_preview/common",
@@ -2217,7 +2218,6 @@
     "weborigin/security_policy_test.cc",
     "webrtc/convert_to_webrtc_video_frame_buffer_test.cc",
     "webrtc/webrtc_video_frame_adapter_test.cc",
-    "widget/compositing/categorized_worker_pool_unittest.cc",
     "widget/compositing/layer_tree_settings_unittest.cc",
     "widget/compositing/layer_tree_view_unittest.cc",
     "widget/compositing/render_frame_metadata_observer_impl_unittest.cc",
diff --git a/third_party/blink/renderer/platform/fonts/mac/attributed_string_type_converter.h b/third_party/blink/renderer/platform/fonts/mac/attributed_string_type_converter.h
index ebc0089..489c289 100644
--- a/third_party/blink/renderer/platform/fonts/mac/attributed_string_type_converter.h
+++ b/third_party/blink/renderer/platform/fonts/mac/attributed_string_type_converter.h
@@ -8,19 +8,15 @@
 #include "third_party/blink/renderer/platform/platform_export.h"
 #include "ui/base/mojom/attributed_string.mojom-blink.h"
 
-#if __OBJC__
-@class NSAttributedString;
-#else
-class NSAttributedString;
-#endif
+#include <CoreFoundation/CoreFoundation.h>
 
 namespace mojo {
 
 template <>
-struct PLATFORM_EXPORT
-    TypeConverter<ui::mojom::blink::AttributedStringPtr, NSAttributedString*> {
+struct PLATFORM_EXPORT TypeConverter<ui::mojom::blink::AttributedStringPtr,
+                                     CFAttributedStringRef> {
   static ui::mojom::blink::AttributedStringPtr Convert(
-      const NSAttributedString* ns_attributed_string);
+      CFAttributedStringRef cf_attributed_string);
 };
 
 }  // namespace mojo
diff --git a/third_party/blink/renderer/platform/fonts/mac/attributed_string_type_converter.mm b/third_party/blink/renderer/platform/fonts/mac/attributed_string_type_converter.mm
index da09b2b..8840acc3 100644
--- a/third_party/blink/renderer/platform/fonts/mac/attributed_string_type_converter.mm
+++ b/third_party/blink/renderer/platform/fonts/mac/attributed_string_type_converter.mm
@@ -6,21 +6,25 @@
 
 #include <AppKit/AppKit.h>
 
+#include "base/mac/foundation_util.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 #include "ui/gfx/range/range.h"
 
 namespace mojo {
 
 ui::mojom::blink::AttributedStringPtr
-TypeConverter<ui::mojom::blink::AttributedStringPtr, NSAttributedString*>::
-    Convert(const NSAttributedString* ns_attributed_string) {
+TypeConverter<ui::mojom::blink::AttributedStringPtr, CFAttributedStringRef>::
+    Convert(CFAttributedStringRef cf_attributed_string) {
+  NSAttributedString* ns_attributed_string =
+      base::mac::CFToNSCast(cf_attributed_string);
+
   // Create the return value.
   ui::mojom::blink::AttributedStringPtr attributed_string =
       ui::mojom::blink::AttributedString::New();
-  attributed_string->string = String([ns_attributed_string string]);
+  attributed_string->string = String(ns_attributed_string.string);
 
   // Iterate over all the attributes in the string.
-  NSUInteger length = [ns_attributed_string length];
+  NSUInteger length = ns_attributed_string.length;
   for (NSUInteger i = 0; i < length;) {
     NSRange effective_range;
     NSDictionary* ns_attributes =
@@ -32,8 +36,8 @@
     float font_point_size;
     // Only encode the attributes if the filtered set contains font information.
     if (font) {
-      font_name = String([font fontName]);
-      font_point_size = [font pointSize];
+      font_name = String(font.fontName);
+      font_point_size = font.pointSize;
       if (!font_name.empty()) {
         // Convert the attributes.
         ui::mojom::blink::FontAttributePtr attrs =
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 4d0551c..62ebc03 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -462,7 +462,6 @@
     },
     {
       name: "BlinkLifecycleScriptForbidden",
-      status: "experimental",
     },
     {
       name: "BlinkRuntimeCallStats",
diff --git a/third_party/blink/renderer/platform/scheduler/public/main_thread.h b/third_party/blink/renderer/platform/scheduler/public/main_thread.h
index 49b11b2..b496a5e 100644
--- a/third_party/blink/renderer/platform/scheduler/public/main_thread.h
+++ b/third_party/blink/renderer/platform/scheduler/public/main_thread.h
@@ -16,10 +16,10 @@
 class MainThreadTaskRunnerRestricted {
  private:
   // Permitted users of `MainThread::GetTaskRunner`.
+  friend class BlinkCategorizedWorkerPoolDelegate;
   friend class BlinkInitializer;
   friend class BlobBytesProvider;
   friend class CachedStorageArea;
-  friend class CategorizedWorkerPoolImpl;
   friend class FontCache;
   friend class InspectorNetworkAgent;
   friend class MemoryCache;
diff --git a/third_party/blink/renderer/platform/widget/compositing/DEPS b/third_party/blink/renderer/platform/widget/compositing/DEPS
index 663dc26..43cc687b 100644
--- a/third_party/blink/renderer/platform/widget/compositing/DEPS
+++ b/third_party/blink/renderer/platform/widget/compositing/DEPS
@@ -24,11 +24,4 @@
     "+ui/native_theme/native_theme_features.h",
     "+ui/native_theme/overlay_scrollbar_constants_aura.h",
   ],
-  "categorized_worker_pool\.h": [
-    "+base/task/task_runner.h",
-    "+base/threading/simple_thread.h",
-  ],
-  "categorized_worker_pool_unittest\.cc": [
-    "+base/threading/simple_thread.h",
-  ],
 }
diff --git a/third_party/blink/renderer/platform/widget/compositing/blink_categorized_worker_pool_delegate.cc b/third_party/blink/renderer/platform/widget/compositing/blink_categorized_worker_pool_delegate.cc
new file mode 100644
index 0000000..37010e6
--- /dev/null
+++ b/third_party/blink/renderer/platform/widget/compositing/blink_categorized_worker_pool_delegate.cc
@@ -0,0 +1,43 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/platform/widget/compositing/blink_categorized_worker_pool_delegate.h"
+
+#include "base/memory/scoped_refptr.h"
+#include "base/no_destructor.h"
+#include "build/build_config.h"
+#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/platform/scheduler/public/main_thread.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
+
+namespace blink {
+
+BlinkCategorizedWorkerPoolDelegate::BlinkCategorizedWorkerPoolDelegate() =
+    default;
+
+BlinkCategorizedWorkerPoolDelegate::~BlinkCategorizedWorkerPoolDelegate() =
+    default;
+
+// static
+BlinkCategorizedWorkerPoolDelegate& BlinkCategorizedWorkerPoolDelegate::Get() {
+  static base::NoDestructor<BlinkCategorizedWorkerPoolDelegate> delegate;
+  return *delegate;
+}
+
+void BlinkCategorizedWorkerPoolDelegate::NotifyThreadWillRun(
+    base::PlatformThreadId tid) {
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
+  scoped_refptr<base::TaskRunner> task_runner =
+      Thread::MainThread()->GetTaskRunner(MainThreadTaskRunnerRestricted());
+  task_runner->PostTask(FROM_HERE, base::BindOnce(
+                                       [](base::PlatformThreadId tid) {
+                                         Platform::Current()->SetThreadType(
+                                             tid,
+                                             base::ThreadType::kBackground);
+                                       },
+                                       tid));
+#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/platform/widget/compositing/blink_categorized_worker_pool_delegate.h b/third_party/blink/renderer/platform/widget/compositing/blink_categorized_worker_pool_delegate.h
new file mode 100644
index 0000000..fa2ace8
--- /dev/null
+++ b/third_party/blink/renderer/platform/widget/compositing/blink_categorized_worker_pool_delegate.h
@@ -0,0 +1,28 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_COMPOSITING_BLINK_CATEGORIZED_WORKER_POOL_DELEGATE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_COMPOSITING_BLINK_CATEGORIZED_WORKER_POOL_DELEGATE_H_
+
+#include "base/functional/callback.h"
+#include "cc/raster/categorized_worker_pool.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+
+namespace blink {
+
+class PLATFORM_EXPORT BlinkCategorizedWorkerPoolDelegate
+    : public cc::CategorizedWorkerPool::Delegate {
+ public:
+  BlinkCategorizedWorkerPoolDelegate();
+  ~BlinkCategorizedWorkerPoolDelegate() override;
+
+  static BlinkCategorizedWorkerPoolDelegate& Get();
+
+  // cc::CategorizedWorkerPool::Delegate:
+  void NotifyThreadWillRun(base::PlatformThreadId tid) override;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_COMPOSITING_BLINK_CATEGORIZED_WORKER_POOL_DELEGATE_H_
diff --git a/third_party/blink/renderer/platform/widget/widget_base.cc b/third_party/blink/renderer/platform/widget/widget_base.cc
index e8a1a182..7b92b2c2 100644
--- a/third_party/blink/renderer/platform/widget/widget_base.cc
+++ b/third_party/blink/renderer/platform/widget/widget_base.cc
@@ -14,6 +14,7 @@
 #include "cc/animation/animation_host.h"
 #include "cc/animation/animation_id_provider.h"
 #include "cc/mojo_embedder/async_layer_tree_frame_sink.h"
+#include "cc/raster/categorized_worker_pool.h"
 #include "cc/trees/layer_tree_host.h"
 #include "cc/trees/layer_tree_settings.h"
 #include "cc/trees/paint_holding_reason.h"
@@ -42,7 +43,7 @@
 #include "third_party/blink/renderer/platform/scheduler/public/page_scheduler.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
 #include "third_party/blink/renderer/platform/scheduler/public/widget_scheduler.h"
-#include "third_party/blink/renderer/platform/widget/compositing/categorized_worker_pool.h"
+#include "third_party/blink/renderer/platform/widget/compositing/blink_categorized_worker_pool_delegate.h"
 #include "third_party/blink/renderer/platform/widget/compositing/layer_tree_settings.h"
 #include "third_party/blink/renderer/platform/widget/compositing/layer_tree_view.h"
 #include "third_party/blink/renderer/platform/widget/compositing/render_frame_metadata_observer_impl.h"
@@ -203,7 +204,8 @@
       compositing_thread_scheduler
           ? compositing_thread_scheduler->DefaultTaskRunner()
           : nullptr,
-      CategorizedWorkerPool::GetOrCreate());
+      cc::CategorizedWorkerPool::GetOrCreate(
+          &BlinkCategorizedWorkerPoolDelegate::Get()));
 
   FrameWidget* frame_widget = client_->FrameWidget();
 
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
index dfee0b6..144db955 100755
--- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
+++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
@@ -322,7 +322,8 @@
             'base::TestMockTimeTaskRunner',
             'base::TickClock',
 
-            # cc painting types.
+            # cc painting and raster types.
+            'cc::CategorizedWorkerPool',
             'cc::InspectablePaintRecorder',
             'cc::InspectableRecordPaintCanvas',
             'cc::PaintCanvas',
diff --git a/third_party/blink/tools/blinkpy/tool/commands/lint_wpt.py b/third_party/blink/tools/blinkpy/tool/commands/lint_wpt.py
index 5dfd119..9d781c52 100644
--- a/third_party/blink/tools/blinkpy/tool/commands/lint_wpt.py
+++ b/third_party/blink/tools/blinkpy/tool/commands/lint_wpt.py
@@ -11,18 +11,18 @@
 import optparse
 import pathlib
 import urllib.parse
-from typing import List, Optional, Set, Tuple, Type, Union
+from typing import Collection, List, Optional, Set, Tuple, Type, Union
 
 from blinkpy.common import path_finder
 from blinkpy.common.host import Host
 from blinkpy.tool.commands.command import Command
 from blinkpy.w3c.wpt_manifest import WPTManifest
-from blinkpy.tool.commands.update_metadata import BUG_PATTERN
+from blinkpy.tool.commands.update_metadata import BUG_PATTERN, generate_configs
 
 path_finder.bootstrap_wpt_imports()
 from tools.lint import lint as wptlint
 from tools.lint import rules
-from wptrunner import wptmanifest
+from wptrunner import metadata, wptmanifest
 from wptrunner.manifestexpected import fuzzy_prop
 from wptrunner.wptmanifest import node as wptnode
 from wptrunner.wptmanifest.backends.static import Compiler
@@ -161,14 +161,34 @@
 
 
 class MetadataUnnecessaryCondition(MetadataRule):
-    name = 'META-UNNECESSARY-CONDITION'
+    name = 'META-CONDITIONS-UNNECESSARY'
     description = '%(section_type)s key %(key)r always has value %(value)r'
     to_fix = """
     Express the key as an unconditional expression without `if`.
     """
 
 
+class MetadataUnreachableValue(MetadataRule):
+    name = 'META-UNREACHABLE-VALUE'
+    description = '%(section_type)s key %(key)r has an unused %(condition)s'
+    to_fix = """
+    Check that at least one test configuration takes the condition branch.
+    """
+
+
+class MetadataUnknownProp(MetadataRule):
+    name = 'META-UNKNOWN-PROP'
+    description = ('%(section_type)s key %(key)r %(condition)s '
+                   'uses unrecognized property %(prop)s')
+    to_fix = """
+    Check that all property names are spelled correctly:
+    https://chromium.googlesource.com/chromium/src/+/HEAD/docs/testing/web_platform_tests_wptrunner.md#conditional-values
+    """
+
+
 LintError = Tuple[str, str, str, Optional[int]]
+ValueNode = Union[wptnode.ValueNode, wptnode.AtomNode, wptnode.ListNode]
+Condition = Optional[wptnode.Node]
 
 
 class LintWPT(Command):
@@ -177,12 +197,15 @@
     help_text = __doc__.strip().splitlines()[0]
     long_help = __doc__
 
-    def __init__(self, tool: Host):
+    def __init__(self,
+                 tool: Host,
+                 configs: Optional[Collection[metadata.RunInfo]] = None):
         super().__init__()
         self._tool = tool
         self._fs = self._tool.filesystem
         self._default_port = self._tool.port_factory.get()
         self._finder = path_finder.PathFinder(self._fs)
+        self._configs = configs or generate_configs(self._tool)
 
     def parse_args(self, args: List[str]) -> Tuple[optparse.Values, List[str]]:
         # TODO(crbug.com/1431070): Migrate `blink_tool.py` to stdlib's
@@ -226,7 +249,7 @@
             return [MetadataBadSyntax.error(path, context, error.line)]
 
         test_type = manifest.get_test_type(test_path) if test_path else None
-        linter = MetadataLinter(path, test_type, manifest)
+        linter = MetadataLinter(path, test_type, manifest, self._configs)
         return linter.find_errors(ast)
 
     def _manifest(self, repo_root: str) -> WPTManifest:
@@ -246,10 +269,12 @@
 
 
 class MetadataLinter(Compiler):
-    def __init__(self, path: str, test_type: str, manifest: WPTManifest):
+    def __init__(self, path: str, test_type: str, manifest: WPTManifest,
+                 configs: Collection[metadata.RunInfo]):
         self.path = path
         self.test_type = test_type
         self.manifest = manifest
+        self.configs = configs
         # `context` contains information about the current section type,
         # heading, and key as it becomes available during the traversal. It's
         # also provided to the error message formatter.
@@ -324,20 +349,71 @@
             else:
                 self._check_conditions(node)
 
-    def _check_conditions(self, key_value_node: wptnode.KeyValueNode):
-        conditions = []
+    def _get_conditional_values(
+        self,
+        key_value_node: wptnode.KeyValueNode,
+    ) -> Tuple[List[Condition], List[ValueNode]]:
+        conditions, values = [], []
         for i, child in enumerate(key_value_node.children):
             if isinstance(child, wptnode.ConditionalNode):
-                cond_expr, value = child.children
+                condition, value = child.children
             else:
                 assert i == len(key_value_node.children) - 1
-                cond_expr, value = None, child
-            conditions.append((cond_expr, value))
-        values = {self.visit(value) for _, value in conditions}
-        if len(conditions) > 1 and len(values) == 1:
-            (_, value), *_ = conditions
+                condition, value = None, child
+            conditions.append(condition)
+            values.append(value)
+        return conditions, values
+
+    def _check_conditions(self, key_value_node: wptnode.KeyValueNode):
+        conditions, values = self._get_conditional_values(key_value_node)
+        # Reference conditions by index because they are not hashable.
+        conditions_not_taken = set(range(len(conditions)))
+        unique_values = set(map(self.visit, values))
+        # Simulate conditional value resolution for each test configuration.
+        for config in self.configs:
+            for i, condition in enumerate(conditions):
+                try:
+                    if self._eval_condition_taken(condition, config):
+                        # Mark this condition as having been exercised.
+                        conditions_not_taken.discard(i)
+                        break
+                except KeyError as error:
+                    self._error(MetadataUnknownProp,
+                                prop=str(error),
+                                condition=_format_condition(condition))
+                    # The conditional expression could not be evaluated because
+                    # of an unknown property. Do not show an unactionable
+                    # `META-UNREACHABLE-VALUE` error for this branch, but act
+                    # as if this branch were not taken.
+                    conditions_not_taken.discard(i)
+            else:
+                # Add a sentinel object to simulate no default (an empty value).
+                # This unique value forces `META-CONDITIONS-UNNECESSARY` to
+                # pass because at least one configuration falls through to the
+                # end.
+                #
+                # TODO(crbug.com/1406669): Add a special rule when
+                # `unique_values` is `expected: (PASS|OK)`, which can just be
+                # removed.
+                unique_values.add(object())
+
+        if (len([condition for condition in conditions if condition]) > 0
+                and len(unique_values) == 1):
             self._error(MetadataUnnecessaryCondition,
-                        value=_format_node(value))
+                        value=_format_node(values[0]))
+        else:
+            # No need to show that condition branches are unreachable if no
+            # conditions are necessary in the first place.
+            for i in conditions_not_taken:
+                self._error(MetadataUnreachableValue,
+                            condition=_format_condition(conditions[i]))
+
+    def _eval_condition_taken(self, condition: Condition,
+                              run_info: metadata.RunInfo) -> bool:
+        if not condition:
+            return True
+        self.expr_data = run_info.data
+        return self.visit(condition)
 
     def visit_ListNode(self,
                        node: wptnode.ListNode) -> Tuple[Union[bool, str]]:
@@ -407,5 +483,12 @@
         return MetadataBadValue.test_statuses
 
 
+def _format_condition(condition: Condition) -> str:
+    if not condition:
+        return 'default condition'
+    formatted_expr = f'if {_format_node(condition)}'
+    return f'condition {formatted_expr!r}'
+
+
 def _format_node(node: wptnode.Node) -> str:
     return wptmanifest.serialize(node).splitlines()[0].strip()
diff --git a/third_party/blink/tools/blinkpy/tool/commands/lint_wpt_unittest.py b/third_party/blink/tools/blinkpy/tool/commands/lint_wpt_unittest.py
index 733b6365..a8d1511d 100644
--- a/third_party/blink/tools/blinkpy/tool/commands/lint_wpt_unittest.py
+++ b/third_party/blink/tools/blinkpy/tool/commands/lint_wpt_unittest.py
@@ -15,6 +15,9 @@
 from blinkpy.tool.commands.lint_wpt import LintError, LintWPT
 from blinkpy.common.system.log_testing import LoggingTestCase
 
+path_finder.bootstrap_wpt_imports()
+from wptrunner import metadata
+
 
 class LintWPTTest(LoggingTestCase):
     def setUp(self):
@@ -23,7 +26,28 @@
         self.tool = MockBlinkTool()
         self.fs = self.tool.filesystem
         self.finder = path_finder.PathFinder(self.fs)
-        self.command = LintWPT(self.tool)
+        configs = [{
+            'os': 'mac',
+            'flag_specific': None,
+            'product': 'content_shell',
+        }, {
+            'os': 'win',
+            'flag_specific': None,
+            'product': 'content_shell',
+        }, {
+            'os': 'linux',
+            'flag_specific': None,
+            'product': 'content_shell',
+        }, {
+            'os': 'linux',
+            'flag_specific': None,
+            'product': 'chrome',
+        }, {
+            'os': 'linux',
+            'flag_specific': 'fake-flag',
+            'product': 'content_shell',
+        }]
+        self.command = LintWPT(self.tool, set(map(metadata.RunInfo, configs)))
         self.fs.write_text_file(self.finder.path_from_wpt_tests('lint.ignore'),
                                 '')
         self.fs.write_text_file(
@@ -101,7 +125,10 @@
             """\
             [variant.html?foo=bar/abc]
               bug: crbug.com/12
-              expected: ERROR
+              expected:
+                if os == "linux" and product == "chrome": [ERROR, TIMEOUT]
+                if os == "linux": ERROR
+                OK
             [variant.html?foo=baz]
               disabled: never completes
               expected: TIMEOUT
@@ -334,29 +361,125 @@
         self.assertEqual(description,
                          "Subtest key 'expected' has invalid value 'CRASH'")
 
-    def test_metadata_unnecessary_conditions(self):
-        exp_error, fuzzy_error = self._check_metadata("""\
+    def test_metadata_conditions_unnecessary(self):
+        exp_error, fuzzy_error, restart_error = self._check_metadata("""\
             [reftest.html]
               disabled:
+                # Does not partition all configurations ('linux' falls through).
                 if os == "mac": flaky
-                if os == "win": @False
-                flaky
+                if os == "win": flaky
               expected:
+                # Partition all configurations, but without using a default.
                 if os == "mac": FAIL
-                FAIL
+                if os == "win": FAIL
+                if os == "linux": FAIL
               fuzzy:
+                # Partition all configurations using a default.
                 if os == "win": [0-1;0-2, reftest-ref.html:20;200-300]
                 [0-1;0-2, reftest-ref.html:20;200-300]
+              restart-after:
+                # Captures all configurations, but not using an unconditional
+                # value.
+                if os == "mac" or os != "mac": @True
             """)
-        # Note that `disabled` is not an error because of `os == "win"`.
         name, description, path, _ = exp_error
-        self.assertEqual(name, 'META-UNNECESSARY-CONDITION')
+        self.assertEqual(name, 'META-CONDITIONS-UNNECESSARY')
         self.assertEqual(path, 'reftest.html.ini')
         self.assertEqual(description,
                          "Test key 'expected' always has value 'FAIL'")
         name, description, path, _ = fuzzy_error
-        self.assertEqual(name, 'META-UNNECESSARY-CONDITION')
+        self.assertEqual(name, 'META-CONDITIONS-UNNECESSARY')
         self.assertEqual(path, 'reftest.html.ini')
         self.assertEqual(
             description, "Test key 'fuzzy' always has value "
             "'[0-1;0-2, reftest-ref.html:20;200-300]'")
+        name, description, path, _ = restart_error
+        self.assertEqual(name, 'META-CONDITIONS-UNNECESSARY')
+        self.assertEqual(path, 'reftest.html.ini')
+        self.assertEqual(description,
+                         "Test key 'restart-after' always has value '@True'")
+
+    def test_metadata_condition_checks_exclusive(self):
+        conds_unnecessary, unreachable_value = self._check_metadata("""\
+            [reftest.html]
+              disabled:
+                if os == "win": flaky
+                if os == "win": flaky
+                flaky
+              expected:
+                if os == "win": FAIL
+                if os == "win": [FAIL, PASS]
+                FAIL
+            """)
+        # Since the author should rewrite this key unconditionally as
+        # `disabled: flaky` anyway, there's no need to say that the second
+        # condition is unreachable.
+        name, description, path, _ = conds_unnecessary
+        self.assertEqual(name, 'META-CONDITIONS-UNNECESSARY')
+        self.assertEqual(path, 'reftest.html.ini')
+        self.assertEqual(description,
+                         "Test key 'disabled' always has value 'flaky'")
+        # `META-CONDITIONS-UNNECESSARY` should determine necessity using all
+        # values, even unreachable ones, as unreachable values may become
+        # reachable if fixed.
+        name, description, path, _ = unreachable_value
+        self.assertEqual(name, 'META-UNREACHABLE-VALUE')
+        self.assertEqual(path, 'reftest.html.ini')
+        self.assertEqual(
+            description,
+            "Test key 'expected' has an unused condition 'if os == \"win\"'")
+
+    def test_metadata_unreachable_value(self):
+        shadowed_narrow, always_false, unused_default = self._check_metadata(
+            """\
+            [reftest.html]
+              expected:
+                if os == "win" and os == "mac": FAIL  # Meant to say `or`.
+                # This branch shadows the next one, which is narrower.
+                if os == "linux": FAIL
+                if os == "linux" and product == "chrome": PASS
+                if os != "linux": FAIL
+                FAIL
+            """)
+        name, description, path, _ = always_false
+        self.assertEqual(name, 'META-UNREACHABLE-VALUE')
+        self.assertEqual(path, 'reftest.html.ini')
+        self.assertEqual(
+            description, "Test key 'expected' has an unused condition "
+            "'if (os == \"win\") and (os == \"mac\")'")
+        name, description, path, _ = shadowed_narrow
+        self.assertEqual(name, 'META-UNREACHABLE-VALUE')
+        self.assertEqual(path, 'reftest.html.ini')
+        self.assertEqual(
+            description, "Test key 'expected' has an unused condition "
+            "'if (os == \"linux\") and (product == \"chrome\")'")
+        name, description, path, _ = unused_default
+        self.assertEqual(name, 'META-UNREACHABLE-VALUE')
+        self.assertEqual(path, 'reftest.html.ini')
+        self.assertEqual(
+            description, "Test key 'expected' has an unused default condition")
+
+    def test_metadata_unknown_prop(self):
+        os_error, product_error = self._check_metadata("""\
+            [reftest.html]
+              disabled:
+                if oss == "win": wontfix
+                if os == "mac": wontfix
+              expected:
+                if os != "linux": PASS
+                # Should be detected even if the expression short-circuits.
+                if os == "linux" or prduct == "chrome": FAIL
+            """)
+        name, description, path, _ = os_error
+        self.assertEqual(name, 'META-UNKNOWN-PROP')
+        self.assertEqual(path, 'reftest.html.ini')
+        self.assertEqual(
+            description, "Test key 'disabled' condition 'if oss == \"win\"' "
+            "uses unrecognized property 'oss'")
+        name, description, path, _ = product_error
+        self.assertEqual(name, 'META-UNKNOWN-PROP')
+        self.assertEqual(path, 'reftest.html.ini')
+        self.assertEqual(
+            description, "Test key 'expected' condition "
+            "'if (os == \"linux\") or (prduct == \"chrome\")' "
+            "uses unrecognized property 'prduct'")
diff --git a/third_party/blink/tools/blinkpy/tool/commands/update_metadata.py b/third_party/blink/tools/blinkpy/tool/commands/update_metadata.py
index 62fed88a..c19c75c2 100644
--- a/third_party/blink/tools/blinkpy/tool/commands/update_metadata.py
+++ b/third_party/blink/tools/blinkpy/tool/commands/update_metadata.py
@@ -170,7 +170,7 @@
         manifests = load_and_update_manifests(self._path_finder)
         updater = MetadataUpdater.from_manifests(
             manifests,
-            self.generate_configs(),
+            generate_configs(self._tool),
             self._tool.filesystem,
             self._explicit_include_patterns(options, args),
             options.exclude,
@@ -473,49 +473,47 @@
                 '%r is neither a regular file nor a directory' % value)
         setattr(parser.values, option.dest, reports)
 
-    def generate_configs(self) -> Dict[metadata.RunInfo, Port]:
-        """Construct run info representing all Chromium test environments.
 
-        Each property in a config represents a value that metadata keys can be
-        conditioned on (e.g., 'os').
-        """
-        configs = {}
-        wptrunner_builders = {
-            builder
-            for builder in self._tool.builders.all_builder_names()
-            if self._tool.builders.uses_wptrunner(builder)
-        }
+def generate_configs(host: Host) -> Dict[metadata.RunInfo, Port]:
+    """Construct run info representing all Chromium test environments.
 
-        for builder in wptrunner_builders:
-            port_name = self._tool.builders.port_name_for_builder_name(builder)
-            _, build_config, *_ = self._tool.builders.specifiers_for_builder(
-                builder)
+    Each property in a config represents a value that metadata keys can be
+    conditioned on (e.g., 'os').
+    """
+    configs = {}
+    wptrunner_builders = {
+        builder
+        for builder in host.builders.all_builder_names()
+        if host.builders.uses_wptrunner(builder)
+    }
 
-            for step in self._tool.builders.step_names_for_builder(builder):
-                flag_specific = self._tool.builders.flag_specific_option(
-                    builder, step)
-                port = self._tool.port_factory.get(
-                    port_name,
-                    optparse.Values({
-                        'configuration': build_config,
-                        'flag_specific': flag_specific,
-                    }))
-                product = self._tool.builders.product_for_build_step(
-                    builder, step)
-                config = metadata.RunInfo({
-                    'product':
-                    product,
-                    'os':
-                    port.operating_system(),
-                    'port':
-                    port.version(),
-                    'debug':
-                    port.get_option('configuration') == 'Debug',
-                    'flag_specific':
-                    flag_specific or '',
-                })
-                configs[config] = port
-        return configs
+    for builder in wptrunner_builders:
+        port_name = host.builders.port_name_for_builder_name(builder)
+        _, build_config, *_ = host.builders.specifiers_for_builder(builder)
+
+        for step in host.builders.step_names_for_builder(builder):
+            flag_specific = host.builders.flag_specific_option(builder, step)
+            port = host.port_factory.get(
+                port_name,
+                optparse.Values({
+                    'configuration': build_config,
+                    'flag_specific': flag_specific,
+                }))
+            product = host.builders.product_for_build_step(builder, step)
+            config = metadata.RunInfo({
+                'product':
+                product,
+                'os':
+                port.operating_system(),
+                'port':
+                port.version(),
+                'debug':
+                port.get_option('configuration') == 'Debug',
+                'flag_specific':
+                flag_specific or '',
+            })
+            configs[config] = port
+    return configs
 
 
 class UpdateAbortError(Exception):
diff --git a/third_party/blink/tools/blinkpy/tool/commands/update_metadata_unittest.py b/third_party/blink/tools/blinkpy/tool/commands/update_metadata_unittest.py
index 94b11da..3d09e1a 100644
--- a/third_party/blink/tools/blinkpy/tool/commands/update_metadata_unittest.py
+++ b/third_party/blink/tools/blinkpy/tool/commands/update_metadata_unittest.py
@@ -18,6 +18,7 @@
 from blinkpy.tool.commands.update_metadata import (
     UpdateMetadata,
     MetadataUpdater,
+    generate_configs,
     load_and_update_manifests,
     sort_metadata_ast,
 )
@@ -561,7 +562,7 @@
 
     def test_generate_configs(self):
         linux, linux_highdpi, mac = sorted(
-            self.command.generate_configs(),
+            generate_configs(self.tool),
             key=lambda config: (config['os'], config['flag_specific']))
 
         self.assertEqual(linux['os'], 'linux')
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/overflow-clip-014.html b/third_party/blink/web_tests/external/wpt/css/css-break/overflow-clip-014.html
new file mode 100644
index 0000000..4edf112e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/overflow-clip-014.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1432946">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div style="columns:2; gap:0; width:100px; height:100px; column-fill:auto; background:red;">
+  <div style="position:relative; overflow-y:clip; height:200px;">
+    <div style="position:absolute; width:100%; height:300px;">
+      <div style="height:200px; background:green;"></div>
+      <div style="height:200px; background:red;"></div>
+    </div>
+    <div style="height:1000px; background:red;"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/overflow-clip-015.html b/third_party/blink/web_tests/external/wpt/css/css-break/overflow-clip-015.html
new file mode 100644
index 0000000..1eb1144
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/overflow-clip-015.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1432946">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div style="columns:2; gap:0; width:100px; height:100px; column-fill:auto; background:red;">
+  <div style="position:relative; overflow-y:clip; height:200px;">
+    <div style="height:150px;"></div>
+    <div style="position:absolute; top:0; width:100%; height:300px;">
+      <div style="height:200px; background:green;"></div>
+      <div style="height:200px; background:red;"></div>
+    </div>
+    <div style="height:1000px; background:red;"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/overflow-clip-016.html b/third_party/blink/web_tests/external/wpt/css/css-break/overflow-clip-016.html
new file mode 100644
index 0000000..4314c01
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/overflow-clip-016.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1432946">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div style="columns:2; gap:0; width:100px; height:100px; column-fill:auto; background:red;">
+  <div style="position:relative; overflow-y:clip; height:200px;">
+    <div style="height:150px;"></div>
+    <div style="position:absolute; top:-100px; width:100%; height:300px;">
+      <div style="height:100px; background:red;"></div>
+      <div style="height:200px; background:green;"></div>
+      <div style="height:200px; background:red;"></div>
+    </div>
+    <div style="height:1000px; background:red;"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/fullscreen/api/element-request-fullscreen-screen-size.https.html b/third_party/blink/web_tests/external/wpt/fullscreen/api/element-request-fullscreen-screen-size.https.html
new file mode 100644
index 0000000..1c2bc9e3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fullscreen/api/element-request-fullscreen-screen-size.https.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<title>
+    Element#requestFullscreen() does not affect Screen sizes
+</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="../trusted-click.js"></script>
+<body></body>
+<script>
+    promise_test(async (t) => {
+        const screenWidth = window.screen.width;
+        const screenHeight = window.screen.height;
+
+        if ('onchange' in window.screen) {
+            window.screen.onchange = () => {
+                assert_equals(window.screen.width, screenWidth);
+                assert_equals(window.screen.height, screenHeight);
+            }
+            t.add_cleanup(() => { window.screen.onchange = null; });
+        }
+
+        // Await a test_driver or manual click, fullscreen promise, and change.
+        await Promise.all([trusted_request(), fullScreenChange()]);
+        t.add_cleanup(() => { document.exitFullscreen(); });
+        assert_not_equals(document.fullscreenElement, null);
+
+        // Ensure the screen size is unchanged during fullscreen.
+        assert_equals(window.screen.width, screenWidth);
+        assert_equals(window.screen.height, screenHeight);
+    }, "Screen size is unchanged during element fullscreen");
+
+    promise_test(async (t) => {
+        const screenWidth = window.screen.width;
+        const screenHeight = window.screen.height;
+
+        if ('onchange' in window.screen) {
+            window.screen.onchange = () => {
+                assert_equals(window.screen.width, screenWidth);
+                assert_equals(window.screen.height, screenHeight);
+            }
+            t.add_cleanup(() => { window.screen.onchange = null; });
+        }
+
+        // Await a test_driver or manual click to start tab content capture.
+        await trusted_click();
+        const stream = await navigator.mediaDevices.getDisplayMedia(
+            {video:{displaySurface:"browser"}, selfBrowserSurface:"include"});
+        const capabilities = stream.getVideoTracks()[0].getCapabilities();
+        assert_equals(capabilities.displaySurface, "browser");
+        t.add_cleanup(() => { stream.getTracks().forEach(t => t.stop()) });
+
+        // Await a test_driver or manual click, fullscreen promise, and change.
+        await Promise.all([trusted_request(), fullScreenChange()]);
+        t.add_cleanup(() => { document.exitFullscreen(); });
+        assert_not_equals(document.fullscreenElement, null);
+
+        // Ensure the screen size is unchanged during tab-capture fullscreen.
+        assert_equals(window.screen.width, screenWidth);
+        assert_equals(window.screen.height, screenHeight);
+    }, "Screen size is unchanged during tab-capture element fullscreen");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.tentative-expected.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.tentative-expected.html
index 62226d7d..8327b5c 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.tentative-expected.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.tentative-expected.html
@@ -4,71 +4,33 @@
 <h1>2d.filter.canvasFilterObject.dropShadow.tentative</h1>
 <p class="desc">Test CanvasFilter() dropShadow object.</p>
 
-<style>
-  .background {
-    background-color: teal;
-    position: absolute;
-    left: 0px;
-    width: 620px;
-    height: 50px;
-  }
+<svg width=620 height=320 xmlns="http://www.w3.org/2000/svg">
+  <rect x=0 y=0 width=100% height=50 fill="teal" />
+  <rect x=0 y=100 width=100% height=50 fill="teal" />
+  <rect x=0 y=200 width=100% height=50 fill="teal" />
 
-  .testcase {
-    position: absolute;
-    background-color: crimson;
-    width: 80px;
-    height: 80px;
-  }
-</style>
+  <rect x=10 y=10 width=80 height=80 fill="crimson"
+        style="filter: drop-shadow(2px 2px 2px black)"/>
+  <rect x=110 y=10 width=80 height=80 fill="crimson"
+        style="filter: drop-shadow(15px 10px 5px rgba(128, 0, 128, 0.7))"/>
 
-<div style="position: relative">
-  <div class="background" style="top: 0px;"></div>
-  <div class="background" style="top: 100px;"></div>
-  <div class="background" style="top: 200px;"></div>
+  <rect x=10 y=110 width=80 height=80 fill="crimson"
+        style="filter: drop-shadow(10px 10px 3px purple)"/>
+  <rect x=110 y=110 width=80 height=80 fill="crimson"
+        style="filter: drop-shadow(15px 10px 3px LinkText)"/>
+  <rect x=210 y=110 width=80 height=80 fill="crimson"
+        style="filter: drop-shadow(10px 15px 0px purple)"/>
+  <rect x=310 y=110 width=80 height=80 fill="crimson"
+        style="filter: drop-shadow(9px 12px 3px rgba(20, 50, 130, 1))"/>
+  <rect x=410 y=110 width=80 height=80 fill="crimson"
+        style="filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.7))"/>
+  <rect x=510 y=110 width=80 height=80 fill="crimson"
+        style="filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.49))"/>
 
-  <div class="testcase"
-       style="left: 10px; top: 10px;
-              filter: drop-shadow(2px 2px 2px black);">
-  </div>
-  <div class="testcase"
-       style="left: 110px; top: 10px;
-              filter: drop-shadow(15px 10px 5px rgba(128, 0, 128, 0.7));">
-  </div>
-  <div class="testcase"
-       style="left: 10px; top: 110px;
-              filter: drop-shadow(10px 10px 3px purple)">
-  </div>
-  <div class="testcase"
-       style="left: 110px; top: 110px;
-              filter: drop-shadow(15px 10px 3px LinkText)">
-  </div>
-  <div class="testcase"
-       style="left: 210px; top: 110px;
-              filter: drop-shadow(10px 15px 0px purple)">
-  </div>
-  <div class="testcase"
-       style="left: 310px; top: 110px;
-              filter: drop-shadow(9px 12px 3px rgba(20, 50, 130, 1))">
-  </div>
-  <div class="testcase"
-       style="left: 410px; top: 110px;
-              filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.7))">
-  </div>
-  <div class="testcase"
-       style="left: 510px; top: 110px;
-              filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.49))">
-  </div>
-
-  <div class="testcase"
-       style="left: 10px; top: 210px;
-              filter: drop-shadow(-5px 0px 0px purple);">
-  </div>
-  <div class="testcase"
-       style="left: 110px; top: 210px;
-              filter: drop-shadow(0px 5px 0px rgba(128, 0, 128, 0.8));">
-  </div>
-  <div class="testcase"
-       style="left: 210px; top: 210px;
-              filter: drop-shadow(1px 10px 0px rgba(128, 0, 128, 0.4));">
-  </div>
-</div>
+  <rect x=10 y=210 width=80 height=80 fill="crimson"
+        style="filter: drop-shadow(-5px 0px 0px purple)"/>
+  <rect x=110 y=210 width=80 height=80 fill="crimson"
+        style="filter: drop-shadow(0px 5px 0px rgba(128, 0, 128, 0.8))"/>
+  <rect x=210 y=210 width=80 height=80 fill="crimson"
+        style="filter: drop-shadow(1px 10px 0px rgba(128, 0, 128, 0.4))"/>
+</svg>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative-expected.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative-expected.html
index 62226d7d..8327b5c 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative-expected.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative-expected.html
@@ -4,71 +4,33 @@
 <h1>2d.filter.canvasFilterObject.dropShadow.tentative</h1>
 <p class="desc">Test CanvasFilter() dropShadow object.</p>
 
-<style>
-  .background {
-    background-color: teal;
-    position: absolute;
-    left: 0px;
-    width: 620px;
-    height: 50px;
-  }
+<svg width=620 height=320 xmlns="http://www.w3.org/2000/svg">
+  <rect x=0 y=0 width=100% height=50 fill="teal" />
+  <rect x=0 y=100 width=100% height=50 fill="teal" />
+  <rect x=0 y=200 width=100% height=50 fill="teal" />
 
-  .testcase {
-    position: absolute;
-    background-color: crimson;
-    width: 80px;
-    height: 80px;
-  }
-</style>
+  <rect x=10 y=10 width=80 height=80 fill="crimson"
+        style="filter: drop-shadow(2px 2px 2px black)"/>
+  <rect x=110 y=10 width=80 height=80 fill="crimson"
+        style="filter: drop-shadow(15px 10px 5px rgba(128, 0, 128, 0.7))"/>
 
-<div style="position: relative">
-  <div class="background" style="top: 0px;"></div>
-  <div class="background" style="top: 100px;"></div>
-  <div class="background" style="top: 200px;"></div>
+  <rect x=10 y=110 width=80 height=80 fill="crimson"
+        style="filter: drop-shadow(10px 10px 3px purple)"/>
+  <rect x=110 y=110 width=80 height=80 fill="crimson"
+        style="filter: drop-shadow(15px 10px 3px LinkText)"/>
+  <rect x=210 y=110 width=80 height=80 fill="crimson"
+        style="filter: drop-shadow(10px 15px 0px purple)"/>
+  <rect x=310 y=110 width=80 height=80 fill="crimson"
+        style="filter: drop-shadow(9px 12px 3px rgba(20, 50, 130, 1))"/>
+  <rect x=410 y=110 width=80 height=80 fill="crimson"
+        style="filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.7))"/>
+  <rect x=510 y=110 width=80 height=80 fill="crimson"
+        style="filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.49))"/>
 
-  <div class="testcase"
-       style="left: 10px; top: 10px;
-              filter: drop-shadow(2px 2px 2px black);">
-  </div>
-  <div class="testcase"
-       style="left: 110px; top: 10px;
-              filter: drop-shadow(15px 10px 5px rgba(128, 0, 128, 0.7));">
-  </div>
-  <div class="testcase"
-       style="left: 10px; top: 110px;
-              filter: drop-shadow(10px 10px 3px purple)">
-  </div>
-  <div class="testcase"
-       style="left: 110px; top: 110px;
-              filter: drop-shadow(15px 10px 3px LinkText)">
-  </div>
-  <div class="testcase"
-       style="left: 210px; top: 110px;
-              filter: drop-shadow(10px 15px 0px purple)">
-  </div>
-  <div class="testcase"
-       style="left: 310px; top: 110px;
-              filter: drop-shadow(9px 12px 3px rgba(20, 50, 130, 1))">
-  </div>
-  <div class="testcase"
-       style="left: 410px; top: 110px;
-              filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.7))">
-  </div>
-  <div class="testcase"
-       style="left: 510px; top: 110px;
-              filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.49))">
-  </div>
-
-  <div class="testcase"
-       style="left: 10px; top: 210px;
-              filter: drop-shadow(-5px 0px 0px purple);">
-  </div>
-  <div class="testcase"
-       style="left: 110px; top: 210px;
-              filter: drop-shadow(0px 5px 0px rgba(128, 0, 128, 0.8));">
-  </div>
-  <div class="testcase"
-       style="left: 210px; top: 210px;
-              filter: drop-shadow(1px 10px 0px rgba(128, 0, 128, 0.4));">
-  </div>
-</div>
+  <rect x=10 y=210 width=80 height=80 fill="crimson"
+        style="filter: drop-shadow(-5px 0px 0px purple)"/>
+  <rect x=110 y=210 width=80 height=80 fill="crimson"
+        style="filter: drop-shadow(0px 5px 0px rgba(128, 0, 128, 0.8))"/>
+  <rect x=210 y=210 width=80 height=80 fill="crimson"
+        style="filter: drop-shadow(1px 10px 0px rgba(128, 0, 128, 0.4))"/>
+</svg>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/filters.yaml b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/filters.yaml
index 46171c1..246b73e 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/filters.yaml
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/filters.yaml
@@ -420,74 +420,36 @@
        floodColor: 'purple', floodOpacity: ['0.4']});
     ctx.fillRect(210, 210, 80, 80);
   html_reference: |
-    <style>
-      .background {
-        background-color: teal;
-        position: absolute;
-        left: 0px;
-        width: 620px;
-        height: 50px;
-      }
+    <svg width=620 height=320 xmlns="http://www.w3.org/2000/svg">
+      <rect x=0 y=0 width=100% height=50 fill="teal" />
+      <rect x=0 y=100 width=100% height=50 fill="teal" />
+      <rect x=0 y=200 width=100% height=50 fill="teal" />
 
-      .testcase {
-        position: absolute;
-        background-color: crimson;
-        width: 80px;
-        height: 80px;
-      }
-    </style>
+      <rect x=10 y=10 width=80 height=80 fill="crimson"
+            style="filter: drop-shadow(2px 2px 2px black)"/>
+      <rect x=110 y=10 width=80 height=80 fill="crimson"
+            style="filter: drop-shadow(15px 10px 5px rgba(128, 0, 128, 0.7))"/>
 
-    <div style="position: relative">
-      <div class="background" style="top: 0px;"></div>
-      <div class="background" style="top: 100px;"></div>
-      <div class="background" style="top: 200px;"></div>
+      <rect x=10 y=110 width=80 height=80 fill="crimson"
+            style="filter: drop-shadow(10px 10px 3px purple)"/>
+      <rect x=110 y=110 width=80 height=80 fill="crimson"
+            style="filter: drop-shadow(15px 10px 3px LinkText)"/>
+      <rect x=210 y=110 width=80 height=80 fill="crimson"
+            style="filter: drop-shadow(10px 15px 0px purple)"/>
+      <rect x=310 y=110 width=80 height=80 fill="crimson"
+            style="filter: drop-shadow(9px 12px 3px rgba(20, 50, 130, 1))"/>
+      <rect x=410 y=110 width=80 height=80 fill="crimson"
+            style="filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.7))"/>
+      <rect x=510 y=110 width=80 height=80 fill="crimson"
+            style="filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.49))"/>
 
-      <div class="testcase"
-           style="left: 10px; top: 10px;
-                  filter: drop-shadow(2px 2px 2px black);">
-      </div>
-      <div class="testcase"
-           style="left: 110px; top: 10px;
-                  filter: drop-shadow(15px 10px 5px rgba(128, 0, 128, 0.7));">
-      </div>
-      <div class="testcase"
-           style="left: 10px; top: 110px;
-                  filter: drop-shadow(10px 10px 3px purple)">
-      </div>
-      <div class="testcase"
-           style="left: 110px; top: 110px;
-                  filter: drop-shadow(15px 10px 3px LinkText)">
-      </div>
-      <div class="testcase"
-           style="left: 210px; top: 110px;
-                  filter: drop-shadow(10px 15px 0px purple)">
-      </div>
-      <div class="testcase"
-           style="left: 310px; top: 110px;
-                  filter: drop-shadow(9px 12px 3px rgba(20, 50, 130, 1))">
-      </div>
-      <div class="testcase"
-           style="left: 410px; top: 110px;
-                  filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.7))">
-      </div>
-      <div class="testcase"
-           style="left: 510px; top: 110px;
-                  filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.49))">
-      </div>
-
-      <div class="testcase"
-           style="left: 10px; top: 210px;
-                  filter: drop-shadow(-5px 0px 0px purple);">
-      </div>
-      <div class="testcase"
-           style="left: 110px; top: 210px;
-                  filter: drop-shadow(0px 5px 0px rgba(128, 0, 128, 0.8));">
-      </div>
-      <div class="testcase"
-           style="left: 210px; top: 210px;
-                  filter: drop-shadow(1px 10px 0px rgba(128, 0, 128, 0.4));">
-      </div>
-    </div>
+      <rect x=10 y=210 width=80 height=80 fill="crimson"
+            style="filter: drop-shadow(-5px 0px 0px purple)"/>
+      <rect x=110 y=210 width=80 height=80 fill="crimson"
+            style="filter: drop-shadow(0px 5px 0px rgba(128, 0, 128, 0.8))"/>
+      <rect x=210 y=210 width=80 height=80 fill="crimson"
+            style="filter: drop-shadow(1px 10px 0px rgba(128, 0, 128, 0.4))"/>
+    </svg>
 
 - name: 2d.filter.canvasFilterObject.dropShadow.exceptions.tentative
   desc: Test exceptions on CanvasFilter() dropShadow object
diff --git a/third_party/blink/web_tests/external/wpt/shared-storage/insecure-context.tentative.http.html b/third_party/blink/web_tests/external/wpt/shared-storage/insecure-context.tentative.http.html
new file mode 100644
index 0000000..7ddf02f86
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/shared-storage/insecure-context.tentative.http.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<body>
+  <script src=/resources/testharness.js></script>
+  <script src=/resources/testharnessreport.js></script>
+  <script>
+    test(t => {
+      assert_equals(window.sharedStorage, undefined);
+    }, 'test window.sharedStorage in insecure context');
+  </script>
+</body>
diff --git a/third_party/blink/web_tests/http/tests/credentialmanagement/credentialscontainer-create-basics.html b/third_party/blink/web_tests/http/tests/credentialmanagement/credentialscontainer-create-basics.html
index b256266..3d18d61 100644
--- a/third_party/blink/web_tests/http/tests/credentialmanagement/credentialscontainer-create-basics.html
+++ b/third_party/blink/web_tests/http/tests/credentialmanagement/credentialscontainer-create-basics.html
@@ -5,7 +5,7 @@
 <script type="module">
 import {AuthenticatorStatus} from '/gen/third_party/blink/public/mojom/webauthn/authenticator.mojom.m.js';
 import {MockAuthenticator} from './resources/mock-navigator-credentials.js';
-import {assertValidMakeCredentialResponse, ATTESTATION_OBJECT, CABLE_AUTHENTICATION, CABLE_REGISTRATION, CLIENT_DATA_JSON, deepCopy, ID, MAKE_CREDENTIAL_OPTIONS, RAW_ID} from './resources/test-inputs.js';
+import {assertValidMakeCredentialResponse, ATTESTATION_OBJECT, CABLE_AUTHENTICATION, CLIENT_DATA_JSON, deepCopy, ID, MAKE_CREDENTIAL_OPTIONS, RAW_ID} from './resources/test-inputs.js';
 
 if (document.location.host != "subdomain.example.test:8443") {
   document.location = "https://subdomain.example.test:8443/credentialmanagement/credentialscontainer-create-basics.html";
@@ -227,16 +227,6 @@
   mockAuthenticator.reset();
   mockAuthenticator.setDefaultsForSuccessfulMakeCredential();
   var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
-  customMakeCredOptions.extensions = {cableRegistration: CABLE_REGISTRATION};
-  return navigator.credentials.create({publicKey: customMakeCredOptions}).then(r => {
-      assertValidMakeCredentialResponse(r);
-  });
-}, "navigator.credentials.create() with cableRegistration extension");
-
-promise_test(t => {
-  mockAuthenticator.reset();
-  mockAuthenticator.setDefaultsForSuccessfulMakeCredential();
-  var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
   customMakeCredOptions.extensions = {cableAuthentication: [CABLE_AUTHENTICATION]};
   return promise_rejects_dom(t, "NotSupportedError",
       navigator.credentials.create({publicKey : customMakeCredOptions}));
diff --git a/third_party/blink/web_tests/http/tests/credentialmanagement/credentialscontainer-get-basics.html b/third_party/blink/web_tests/http/tests/credentialmanagement/credentialscontainer-get-basics.html
index 08347df..f191fe2 100644
--- a/third_party/blink/web_tests/http/tests/credentialmanagement/credentialscontainer-get-basics.html
+++ b/third_party/blink/web_tests/http/tests/credentialmanagement/credentialscontainer-get-basics.html
@@ -6,7 +6,7 @@
 import {SmsStatus} from '/gen/third_party/blink/public/mojom/sms/webotp_service.mojom.m.js';
 import {AuthenticatorStatus} from '/gen/third_party/blink/public/mojom/webauthn/authenticator.mojom.m.js';
 import {MockAuthenticator, MockCredentialManager, MockWebOTPService} from './resources/mock-navigator-credentials.js';
-import {assertValidGetCredentialResponse, CABLE_AUTHENTICATION, CABLE_REGISTRATION, deepCopy, GET_CREDENTIAL_OPTIONS, RAW_ID} from './resources/test-inputs.js';
+import {assertValidGetCredentialResponse, CABLE_AUTHENTICATION, deepCopy, GET_CREDENTIAL_OPTIONS, RAW_ID} from './resources/test-inputs.js';
 
 if (document.location.host != "subdomain.example.test:8443") {
   document.location = "https://subdomain.example.test:8443/credentialmanagement/credentialscontainer-get-basics.html";
@@ -242,15 +242,6 @@
   });
 }, "navigator.credentials.get() with missing user verification requirement");
 
-promise_test(t => {
-  mockAuthenticator.reset();
-  mockAuthenticator.setDefaultsForSuccessfulGetAssertion();
-  var customGetCredentialOptions = deepCopy(GET_CREDENTIAL_OPTIONS);
-  customGetCredentialOptions.extensions = {cableRegistration: CABLE_REGISTRATION};
-  return promise_rejects_dom(t, "NotSupportedError",
-      navigator.credentials.get({ publicKey : customGetCredentialOptions}));
-}, "navigator.credentials.get() with cableRegistration extension not supported");
-
 promise_test(_ => {
   mockAuthenticator.reset();
   mockAuthenticator.setDefaultsForSuccessfulGetAssertion();
diff --git a/third_party/blink/web_tests/http/tests/credentialmanagement/resources/test-inputs.js b/third_party/blink/web_tests/http/tests/credentialmanagement/resources/test-inputs.js
index 04d30e2a..83c351f 100644
--- a/third_party/blink/web_tests/http/tests/credentialmanagement/resources/test-inputs.js
+++ b/third_party/blink/web_tests/http/tests/credentialmanagement/resources/test-inputs.js
@@ -57,10 +57,6 @@
 export const AUTHENTICATOR_DATA =
     new TextEncoder("utf-8").encode("authenticatorData");
 export const SIGNATURE = new TextEncoder("utf-8").encode("signature");
-export const CABLE_REGISTRATION = {
-    versions: [1],
-    rpPublicKey: new TextEncoder("utf-8").encode("SixteenByteRpKey"),
-};
 
 export const CABLE_AUTHENTICATION = {
     version: 1,
diff --git a/third_party/blink/web_tests/wpt_internal/shared_storage/add-module.html b/third_party/blink/web_tests/wpt_internal/shared_storage/add-module.https.html
similarity index 100%
rename from third_party/blink/web_tests/wpt_internal/shared_storage/add-module.html
rename to third_party/blink/web_tests/wpt_internal/shared_storage/add-module.https.html
diff --git a/third_party/blink/web_tests/wpt_internal/shared_storage/run-operation-in-detached-frame.html b/third_party/blink/web_tests/wpt_internal/shared_storage/run-operation-in-detached-frame.https.html
similarity index 100%
rename from third_party/blink/web_tests/wpt_internal/shared_storage/run-operation-in-detached-frame.html
rename to third_party/blink/web_tests/wpt_internal/shared_storage/run-operation-in-detached-frame.https.html
diff --git a/third_party/blink/web_tests/wpt_internal/shared_storage/run-operation-keep-alive.html b/third_party/blink/web_tests/wpt_internal/shared_storage/run-operation-keep-alive.https.html
similarity index 100%
rename from third_party/blink/web_tests/wpt_internal/shared_storage/run-operation-keep-alive.html
rename to third_party/blink/web_tests/wpt_internal/shared_storage/run-operation-keep-alive.https.html
diff --git a/third_party/blink/web_tests/wpt_internal/shared_storage/run-operation.html b/third_party/blink/web_tests/wpt_internal/shared_storage/run-operation.https.html
similarity index 100%
rename from third_party/blink/web_tests/wpt_internal/shared_storage/run-operation.html
rename to third_party/blink/web_tests/wpt_internal/shared_storage/run-operation.https.html
diff --git a/third_party/blink/web_tests/wpt_internal/shared_storage/run-url-selection-operation-without-add-module.html b/third_party/blink/web_tests/wpt_internal/shared_storage/run-url-selection-operation-without-add-module.https.html
similarity index 100%
rename from third_party/blink/web_tests/wpt_internal/shared_storage/run-url-selection-operation-without-add-module.html
rename to third_party/blink/web_tests/wpt_internal/shared_storage/run-url-selection-operation-without-add-module.https.html
diff --git a/third_party/blink/web_tests/wpt_internal/shared_storage/setters.html b/third_party/blink/web_tests/wpt_internal/shared_storage/setters.https.html
similarity index 100%
rename from third_party/blink/web_tests/wpt_internal/shared_storage/setters.html
rename to third_party/blink/web_tests/wpt_internal/shared_storage/setters.https.html
diff --git a/third_party/nearby/README.chromium b/third_party/nearby/README.chromium
index be0c3b4..8b413d6 100644
--- a/third_party/nearby/README.chromium
+++ b/third_party/nearby/README.chromium
@@ -1,7 +1,7 @@
 Name: Nearby Connections Library
 Short Name: Nearby
 URL: https://github.com/google/nearby
-Version: 472a1d847b581b73bb577de6a063214606d9a685
+Version: b023a666b95f94be4f9b2070c4d0055ced78ea19
 License: Apache 2.0
 License File: LICENSE
 Security Critical: yes
diff --git a/tools/clang/scripts/upload_revision.py b/tools/clang/scripts/upload_revision.py
index d904c2e1f..acbb5c27 100755
--- a/tools/clang/scripts/upload_revision.py
+++ b/tools/clang/scripts/upload_revision.py
@@ -49,6 +49,10 @@
     'mac_upload_clang',
     'mac_upload_clang_arm',
     'win_upload_clang',
+    'linux_upload_rust',
+    'mac_upload_rust',
+    'mac_upload_rust_arm',
+    'win_upload_rust',
 ]
 
 # Keep lines in here at <= 72 columns, else they wrap in gerrit.
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index c5544856..c4de8e5 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -47,6 +47,11 @@
       'linux-password-manager-captured-sites-rel': 'release_bot',
     },
 
+    'chrome.gpu.fyi': {
+      'Lacros FYI Release (eve)': 'gpu_fyi_tests_lacros_eve_release_trybot_dcheck_off_no_symbols_reclient',
+      'Lacros FYI Release (jacuzzi)': 'gpu_fyi_tests_lacros_jacuzzi_release_trybot_dcheck_off_no_symbols_reclient',
+    },
+
     'chrome.pgo': {
       'android-arm32-pgo': 'official_reclient_android_arm32_pgo',
       'android-arm64-pgo': 'official_reclient_android_arm64_pgo',
@@ -385,7 +390,7 @@
         'build2': 'ios_simulator_debug_static_bot_xctest_reclient',
       },
       'Linux Builder (j-500) (reclient)': 'gpu_tests_release_bot_reclient',
-      'Linux Builder (reclient compare)': 'gpu_tests_release_bot_remote_links_small_reclient',
+      'Linux Builder (reclient compare)': 'gpu_tests_release_bot_reclient',
       'Linux Viz': 'release_trybot_minimal_symbols_reclient',
       # TODO(crbug.com/1260232): remove this after the migration.
       'Mac Builder (reclient compare)': 'gpu_tests_release_bot_minimal_symbols_reclient',
@@ -921,10 +926,6 @@
       'fuchsia-x64': 'official_fuchsia_x64',
     },
 
-    'official.chrome.continuous': {
-      'chromeos-amd64-generic-lacros-internal': 'chromeos_amd64-generic_lacros_official',
-    },
-
     'tryserver.blink': {
       # Most tryservers should have '_trybot' in their config names, but
       # 'release_trybot' includes 'dcheck_always_on', and the blink
@@ -2636,6 +2637,16 @@
       'gpu_fyi_tests', 'dx12vk', 'release_trybot_minimal_symbols_reclient', 'disable_nacl',
     ],
 
+    'gpu_fyi_tests_lacros_eve_release_trybot_dcheck_off_no_symbols_reclient': [
+      'chromeos', 'eve', 'official', 'release_bot_reclient','no_symbols',
+      'chromeos_device_reclient', 'also_build_lacros_chrome_for_architecture_amd64',
+    ],
+
+    'gpu_fyi_tests_lacros_jacuzzi_release_trybot_dcheck_off_no_symbols_reclient': [
+      'chromeos', 'jacuzzi', 'official', 'release_bot_reclient', 'no_symbols',
+      'chromeos_device_reclient', 'also_build_lacros_chrome_for_architecture_arm',
+    ],
+
     'gpu_fyi_tests_release_trybot_arm64_reclient': [
       'gpu_fyi_tests', 'release_trybot_minimal_symbols_reclient', 'arm64', 'disable_nacl',
     ],
diff --git a/tools/mb/mb_config_expectations/chrome.gpu.fyi.json b/tools/mb/mb_config_expectations/chrome.gpu.fyi.json
new file mode 100644
index 0000000..9fb2cdb
--- /dev/null
+++ b/tools/mb/mb_config_expectations/chrome.gpu.fyi.json
@@ -0,0 +1,32 @@
+{
+  "Lacros FYI Release (eve)": {
+    "args_file": "//build/args/chromeos/eve.gni",
+    "gn_args": {
+      "also_build_lacros_chrome_for_architecture": "amd64",
+      "dcheck_always_on": false,
+      "is_chrome_branded": true,
+      "is_chromeos_device": true,
+      "is_component_build": false,
+      "is_debug": false,
+      "is_official_build": true,
+      "symbol_level": 0,
+      "target_os": "chromeos",
+      "use_remoteexec": true
+    }
+  },
+  "Lacros FYI Release (jacuzzi)": {
+    "args_file": "//build/args/chromeos/jacuzzi.gni",
+    "gn_args": {
+      "also_build_lacros_chrome_for_architecture": "arm",
+      "dcheck_always_on": false,
+      "is_chrome_branded": true,
+      "is_chromeos_device": true,
+      "is_component_build": false,
+      "is_debug": false,
+      "is_official_build": true,
+      "symbol_level": 0,
+      "target_os": "chromeos",
+      "use_remoteexec": true
+    }
+  }
+}
\ No newline at end of file
diff --git a/tools/mb/mb_config_expectations/chromium.fyi.json b/tools/mb/mb_config_expectations/chromium.fyi.json
index 83745eee8..27a2e7a 100644
--- a/tools/mb/mb_config_expectations/chromium.fyi.json
+++ b/tools/mb/mb_config_expectations/chromium.fyi.json
@@ -243,15 +243,12 @@
   },
   "Linux Builder (reclient compare)": {
     "gn_args": {
-      "concurrent_links": 50,
       "dcheck_always_on": false,
       "ffmpeg_branding": "Chrome",
       "is_component_build": false,
       "is_debug": false,
       "proprietary_codecs": true,
-      "rbe_link_cfg_file": "../../buildtools/reclient_cfgs/rewrapper_linux_link.cfg",
-      "use_remoteexec": true,
-      "use_remoteexec_links": true
+      "use_remoteexec": true
     }
   },
   "Linux Viz": {
diff --git a/tools/mb/mb_config_expectations/official.chrome.continuous.json b/tools/mb/mb_config_expectations/official.chrome.continuous.json
deleted file mode 100644
index 080a886..0000000
--- a/tools/mb/mb_config_expectations/official.chrome.continuous.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "chromeos-amd64-generic-lacros-internal": {
-    "args_file": "//build/args/chromeos/amd64-generic-crostoolchain.gni",
-    "gn_args": {
-      "chromeos_is_browser_only": true,
-      "dcheck_always_on": false,
-      "is_cfi": true,
-      "is_chrome_branded": true,
-      "is_chromeos_device": true,
-      "is_official_build": true,
-      "ozone_platform_headless": true,
-      "symbol_level": 1,
-      "target_os": "chromeos",
-      "use_goma": true,
-      "use_thin_lto": true
-    }
-  }
-}
\ No newline at end of file
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index c4e6c9f..e3d87b5 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -11925,9 +11925,9 @@
 <enum name="BookmarksSidePanelSortType">
   <int value="0" label="Newest"/>
   <int value="1" label="Oldest"/>
-  <int value="2" label="Alphabetical"/>
-  <int value="3" label="Reverse Alphabetical"/>
-  <int value="4" label="Last Opened"/>
+  <int value="2" label="Last Opened"/>
+  <int value="3" label="Alphabetical"/>
+  <int value="4" label="Reverse Alphabetical"/>
 </enum>
 
 <enum name="BookmarksSidePanelViewType">
@@ -94505,29 +94505,13 @@
   <int value="1" label="Fail to create shortcut"/>
 </enum>
 
-<enum name="ShortcutsMenuRegistrationWinResult">
-  <obsolete>
-    Removed January 2021.
-  </obsolete>
-  <summary>
-    Result of registering app icon shortcuts menu for PWA on Windows
-  </summary>
+<enum name="ShortcutsMenuWinRegistrationResult">
   <int value="0" label="Success"/>
-  <int value="1" label="Failed to write ico files to disk"/>
-  <int value="2" label="Failed to BeginUpdate"/>
-  <int value="3" label="Failed to AddTasks"/>
-  <int value="4" label="Failed to CommitUpdate"/>
-</enum>
-
-<enum name="ShortcutsMenuUnregistrationWinResult">
-  <obsolete>
-    Removed January 2021.
-  </obsolete>
-  <summary>
-    Result of registering app icon shortcuts menu for PWA on Windows
-  </summary>
-  <int value="0" label="Success"/>
-  <int value="1" label="Failed to DeleteJumpList"/>
+  <int value="1" label="Failed to create shortcuts menu icons directory"/>
+  <int value="2" label="Failed to create icon from image family"/>
+  <int value="3" label="Failed to begin jump list update"/>
+  <int value="4" label="Failed to add link items to jump list"/>
+  <int value="5" label="Failed to commit update to jump list"/>
 </enum>
 
 <enum name="ShortProcessType">
diff --git a/tools/metrics/histograms/metadata/compositing/histograms.xml b/tools/metrics/histograms/metadata/compositing/histograms.xml
index 89fe8ca..9c0db18d 100644
--- a/tools/metrics/histograms/metadata/compositing/histograms.xml
+++ b/tools/metrics/histograms/metadata/compositing/histograms.xml
@@ -357,13 +357,13 @@
 
 <histogram
     name="Compositing.Display.HardwareDisplayController.SchedulePageFlipResult"
-    enum="PageFlipResult" expires_after="2023-03-02">
-  <owner>jshargo@chromium.org</owner>
+    enum="PageFlipResult" expires_after="2024-03-02">
   <owner>seanpaul@chromium.org</owner>
   <owner>chromeos-gfx-compositor@chromium.org</owner>
   <summary>
     Logged once per frame, represents whether we could successfully schedule a
-    page flip, or what error we encountered along the way.
+    page flip, or what error we encountered along the way. Note: this metric was
+    expired from 2023-03-02 to 2023-04-13.
   </summary>
 </histogram>
 
@@ -461,10 +461,14 @@
 
 <histogram
     name="Compositing.Display.OverlayProcessorUsingStrategy.NumOverlays{Counted}"
-    units="overlay candidates" expires_after="2022-11-30">
+    units="overlay candidates" expires_after="2023-11-30">
   <owner>khaslett@chromium.org</owner>
   <owner>kylechar@chromium.org</owner>
-  <summary>Logged once per frame, the number of overlays {Counted}</summary>
+  <owner>chromeos-gfx-compositor@chromium.org</owner>
+  <summary>
+    Logged once per frame, the number of overlays {Counted}. Note: this metric
+    was expired from 2022-11-30 to 2023-04-13.
+  </summary>
   <token key="Counted">
     <variant name="Attempted"
         summary="attempted. This is only logged when using the
@@ -510,6 +514,17 @@
   </summary>
 </histogram>
 
+<histogram name="Compositing.Display.PendingSwaps" units="swaps"
+    expires_after="2024-04-11">
+  <owner>sashamcintosh@chromium.org</owner>
+  <owner>chromeos-gfx@chromium.org</owner>
+  <summary>
+    Records the count of pending swaps in the display scheduler. Length of the
+    swap chain can be used as a rough approximation for input latency. Recorded
+    before the swap executes. Refer to Display::DrawAndSwap for details.
+  </summary>
+</histogram>
+
 <histogram name="Compositing.Display.VizDependencyResolvedToGpuStartedDrawUs"
     units="microseconds" expires_after="2022-12-18">
   <owner>vasilyt@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/gpu/histograms.xml b/tools/metrics/histograms/metadata/gpu/histograms.xml
index f479274b..39e9326 100644
--- a/tools/metrics/histograms/metadata/gpu/histograms.xml
+++ b/tools/metrics/histograms/metadata/gpu/histograms.xml
@@ -1701,6 +1701,20 @@
   </token>
 </histogram>
 
+<histogram name="Viz.FrameSink.GpuBusyDuration" units="microseconds"
+    expires_after="2024-04-11">
+  <owner>sashamcintosh@chromium.org</owner>
+  <owner>chromeos-gfx@chromium.org</owner>
+  <summary>
+    The time that a begin frame is throttled due to max pending swaps. Recorded
+    when draw and swap executes (only when a frame is throttled). Refer to
+    BeginFrameSource::SetIsGpuBusy for details.
+
+    Warning: This metric does not include reports from clients with
+    low-resolution clocks.
+  </summary>
+</histogram>
+
 <histogram name="Viz.FrameSinkVideoCapturer.CaptureDuration" units="ms"
     expires_after="2023-07-15">
   <owner>bialpio@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
index d14ea260..4f5c0dc 100644
--- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
+++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -300,6 +300,17 @@
   </summary>
 </histogram>
 
+<histogram name="SafeBrowsing.BrowserThrottle.RedirectedOriginalUrlScheme"
+    enum="SafeBrowsingUrlScheme" expires_after="2023-07-12">
+  <owner>xinghuilu@chromium.org</owner>
+  <owner>chrome-counter-abuse-alerts@google.com</owner>
+  <summary>
+    Logs the scheme of the original URL that is redirected. Logged each time
+    browser URL loader throttle receives a redirect request. This histogram can
+    help us determine what scheme is safe to skip when the request starts.
+  </summary>
+</histogram>
+
 <histogram name="SafeBrowsing.BrowserThrottle.TotalDelay" units="ms"
     expires_after="2023-09-17">
   <owner>xinghuilu@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/webapps/histograms.xml b/tools/metrics/histograms/metadata/webapps/histograms.xml
index 33a4427..acb44aa 100644
--- a/tools/metrics/histograms/metadata/webapps/histograms.xml
+++ b/tools/metrics/histograms/metadata/webapps/histograms.xml
@@ -1384,6 +1384,16 @@
   </summary>
 </histogram>
 
+<histogram name="WebApp.ShortcutsMenu.Win.Results"
+    enum="ShortcutsMenuWinRegistrationResult" expires_after="2024-04-10">
+  <owner>dibyapal@chromium.org</owner>
+  <owner>desktop-pwas-team@google.com</owner>
+  <summary>
+    Records the different results (both failure and success) that contributes to
+    shortcuts menu registration on Windows.
+  </summary>
+</histogram>
+
 <histogram name="WebApp.ShortcutsMenuRegistration.Result" enum="BooleanSuccess"
     expires_after="2023-09-10">
   <owner>dibyapal@chromium.org</owner>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml
index e9f31cf..6096b69 100644
--- a/tools/metrics/ukm/ukm.xml
+++ b/tools/metrics/ukm/ukm.xml
@@ -1180,6 +1180,9 @@
   </metric>
   <metric name="SubFrame.LayoutInstability.CumulativeShiftScore">
     <summary>
+      Deprecated as of 04/23. It is still reported, but most users should use
+      AmpPageLoad.SubFrame.LayoutInstability.MaxCumulativeShiftScore.SessionWindow.Gap1000ms.Max5000ms.
+
       Measures the cumulative layout shift (bit.ly/lsm-explainer) that has
       occurred during the session, in the AMP subframe. This metric's integral
       value is 100x the fractional cumulative layout shift score described in
@@ -10698,6 +10701,9 @@
   </metric>
   <metric name="CumulativeShiftScoreAfterBackForwardCacheRestore">
     <summary>
+      Deprecated as of 04/23. It is still reported, but most users should use
+      PageLoad.LayoutInstability.MaxCumulativeShiftScore.AfterBackForwardCacheRestore.SessionWindow.Gap1000ms.Max5000ms.
+
       Measures the cumulative layout shift (bit.ly/3fQz29y) that has occurred
       during the session, after the page is restored from the back-forward
       cache. This metric's integral value is 100x the fractional cumulative
@@ -16016,6 +16022,9 @@
   </metric>
   <metric name="LayoutInstability.CumulativeShiftScore">
     <summary>
+      Deprecated as of 04/23. It is still reported, but most users should use
+      PageLoad.LayoutInstability.MaxCumulativeShiftScore.SessionWindow.Gap1000ms.Max5000ms.
+
       Measures the cumulative layout shift (bit.ly/lsm-explainer) that has
       occurred on the page (including all subframes) during the session. This
       metric's integral value is 100x the fractional cumulative layout shift
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index c089caf0..98e1ef1 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,24 +5,24 @@
             "full_remote_path": "perfetto-luci-artifacts/adbbb6c78e3a86c5e87b0338d9e42eb6b4ddbf4d/linux-arm64/trace_processor_shell"
         },
         "win": {
-            "hash": "82a32facded20e5c34bf09833eed3c66fc0bcbbc",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/75c6500b8dabe5344ac0255cb3d33182b4fd161f/trace_processor_shell.exe"
+            "hash": "daedf5a7cc393fcae54504ad1e553bbaa6df7865",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/1c46d9577664f7cd811b4fe9c884f66a99697615/trace_processor_shell.exe"
         },
         "linux_arm": {
             "hash": "1d229abc94dea54ab4bb4327e78e18f942d08bf9",
             "full_remote_path": "perfetto-luci-artifacts/adbbb6c78e3a86c5e87b0338d9e42eb6b4ddbf4d/linux-arm/trace_processor_shell"
         },
         "mac": {
-            "hash": "6edc909e16765b71ac1cee1879f128cefd462588",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/75c6500b8dabe5344ac0255cb3d33182b4fd161f/trace_processor_shell"
+            "hash": "75f30b60b6f93968be7e00e147841d6c2a450fa2",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/1c46d9577664f7cd811b4fe9c884f66a99697615/trace_processor_shell"
         },
         "mac_arm64": {
             "hash": "7a4026b8718994145a52586fdec6e9447573345a",
             "full_remote_path": "perfetto-luci-artifacts/adbbb6c78e3a86c5e87b0338d9e42eb6b4ddbf4d/mac-arm64/trace_processor_shell"
         },
         "linux": {
-            "hash": "dfe4c313e49ac49d4d631f444f2a95d9dd27055f",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/75c6500b8dabe5344ac0255cb3d33182b4fd161f/trace_processor_shell"
+            "hash": "da16e9da095315beeb331c2736f4933b48938dbe",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/fe416a62fd4b3a04c0efa38dcfe365fd1611ae6d/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn
index ee38f17..958bed82 100644
--- a/ui/android/BUILD.gn
+++ b/ui/android/BUILD.gn
@@ -43,6 +43,9 @@
     "screen_android.h",
     "toast_manager.cc",
     "ui_android_export.h",
+    "ui_android_feature_list.cc",
+    "ui_android_features.cc",
+    "ui_android_features.h",
     "view_android.cc",
     "view_android.h",
     "view_android_observer.h",
@@ -79,6 +82,18 @@
   ]
 }
 
+java_cpp_features("java_features_srcjar") {
+  # External code should depend on ":android_java" instead.
+  visibility = [ ":*" ]
+  sources = [ "//ui/android/ui_android_features.cc" ]
+  template = "//ui/android/java_templates/UiAndroidFeatures.java.tmpl"
+}
+
+# A minimal library used to expose ui features to webview
+android_library("ui_android_features_java") {
+  srcjar_deps = [ ":java_features_srcjar" ]
+}
+
 static_library("test_support") {
   testonly = true
   sources = [
@@ -96,6 +111,7 @@
   sources = [
     "java/src/org/chromium/ui/OverscrollRefreshHandler.java",
     "java/src/org/chromium/ui/base/EventForwarder.java",
+    "java/src/org/chromium/ui/base/UiAndroidFeatureList.java",
     "java/src/org/chromium/ui/base/ViewAndroidDelegate.java",
     "java/src/org/chromium/ui/base/WindowAndroid.java",
     "java/src/org/chromium/ui/display/DisplayAndroidManager.java",
@@ -273,6 +289,7 @@
     "java/src/org/chromium/ui/base/SPenSupport.java",
     "java/src/org/chromium/ui/base/SelectFileDialog.java",
     "java/src/org/chromium/ui/base/TouchDevice.java",
+    "java/src/org/chromium/ui/base/UiAndroidFeatureList.java",
     "java/src/org/chromium/ui/base/ViewAndroidDelegate.java",
     "java/src/org/chromium/ui/base/ViewUtils.java",
     "java/src/org/chromium/ui/base/ViewportInsets.java",
@@ -381,6 +398,7 @@
     "java/src/org/chromium/ui/widget/ViewRectProvider.java",
   ]
   deps = [
+    ":ui_android_features_java",
     ":ui_java_resources",
     ":ui_utils_java",
     "//base:base_java",
@@ -504,6 +522,7 @@
     "junit/src/org/chromium/ui/AsyncViewStubTest.java",
     "junit/src/org/chromium/ui/base/ApplicationViewportInsetSupplierTest.java",
     "junit/src/org/chromium/ui/base/ClipboardTest.java",
+    "junit/src/org/chromium/ui/base/EventForwarderTest.java",
     "junit/src/org/chromium/ui/base/EventOffsetHandlerTest.java",
     "junit/src/org/chromium/ui/base/LocalizationUtilsTest.java",
     "junit/src/org/chromium/ui/base/MimeTypeUtilsTest.java",
diff --git a/ui/android/java/src/org/chromium/ui/base/EventForwarder.java b/ui/android/java/src/org/chromium/ui/base/EventForwarder.java
index cef17b0..bc9d60e 100644
--- a/ui/android/java/src/org/chromium/ui/base/EventForwarder.java
+++ b/ui/android/java/src/org/chromium/ui/base/EventForwarder.java
@@ -28,13 +28,12 @@
 
 import java.lang.reflect.UndeclaredThrowableException;
 
-/**
- * Class used to forward view, input events down to native.
- */
+/** Class used to forward view, input events down to native. */
 @JNINamespace("ui")
 public class EventForwarder {
     private static final String TAG = "EventForwarder";
     private final boolean mIsDragDropEnabled;
+    private final boolean mConvertTrackpadEventsToMouse;
 
     private long mNativeEventForwarder;
 
@@ -50,9 +49,7 @@
     // Delegate to call WebContents functionality.
     private StylusWritingDelegate mStylusWritingDelegate;
 
-    /**
-     * Interface to provide stylus writing functionality.
-     */
+    /** Interface to provide stylus writing functionality. */
     public interface StylusWritingDelegate {
         /**
          * Handle touch events for stylus handwriting.
@@ -80,12 +77,16 @@
 
     @CalledByNative
     private static EventForwarder create(long nativeEventForwarder, boolean isDragDropEnabled) {
-        return new EventForwarder(nativeEventForwarder, isDragDropEnabled);
+        return new EventForwarder(nativeEventForwarder, isDragDropEnabled,
+                UiAndroidFeatureList.isEnabled(UiAndroidFeatures.CONVERT_TRACKPAD_EVENTS_TO_MOUSE));
     }
 
-    private EventForwarder(long nativeEventForwarder, boolean isDragDropEnabled) {
+    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+    EventForwarder(long nativeEventForwarder, boolean isDragDropEnabled,
+            boolean convertTrackpadEventsToMouse) {
         mNativeEventForwarder = nativeEventForwarder;
         mIsDragDropEnabled = isDragDropEnabled;
+        mConvertTrackpadEventsToMouse = convertTrackpadEventsToMouse;
     }
 
     @CalledByNative
@@ -141,18 +142,40 @@
             logActionDown(event);
         }
 
-        if (mStylusWritingDelegate != null && mStylusWritingDelegate.handleTouchEvent(event)) {
-            // Stylus writing system can consume the touch events once writing is started.
+        if (touchEventRequiresSpecialHandling(event)) {
             return true;
         }
 
-        // TODO(mustaq): Should we include MotionEvent.TOOL_TYPE_STYLUS here?
-        // crbug.com/592082
-        if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) {
-            // Skip firing mouse events in the follwoing cases:
+        final boolean isTouchHandleEvent = false;
+        return sendTouchEvent(event, isTouchHandleEvent);
+    }
+
+    /**
+     * Called by PopupWindow-based touch handles.
+     *
+     * @param event the MotionEvent targeting the handle.
+     */
+    public boolean onTouchHandleEvent(MotionEvent event) {
+        final boolean isTouchHandleEvent = true;
+        return sendTouchEvent(event, isTouchHandleEvent);
+    }
+
+    private boolean touchEventRequiresSpecialHandling(MotionEvent event) {
+        if (mStylusWritingDelegate != null && mStylusWritingDelegate.handleTouchEvent(event)) {
+            // Stylus writing system can consume the touch events once writing is started.
+            return true;
+        } else if (isTrackpadToMouseEventConversionEnabled()
+                && isTrackpadClickOrClickAndDragEvent(event)) {
+            return onMouseEvent(event);
+        } else if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) {
+            // TODO(mustaq): Should we include MotionEvent.TOOL_TYPE_STYLUS here?
+            // crbug.com/592082
+
+            // Skip firing mouse events in the following cases:
             // - In Android L and below, where mouse button info is incomplete.
             // - A move w/o a button press, which represents a trackpad scroll. Real mouse moves w/o
             //   buttons goes to onHoverEvent.
+            // TODO(mustaq): Look into the relevancy of this code path
             final boolean isTouchpadScroll = event.getButtonState() == 0
                     && (event.getActionMasked() == MotionEvent.ACTION_DOWN
                             || event.getActionMasked() == MotionEvent.ACTION_MOVE
@@ -163,18 +186,7 @@
                 return onMouseEvent(event);
             }
         }
-
-        final boolean isTouchHandleEvent = false;
-        return sendTouchEvent(event, isTouchHandleEvent);
-    }
-
-    /**
-     * Called by PopupWindow-based touch handles.
-     * @param event the MotionEvent targeting the handle.
-     */
-    public boolean onTouchHandleEvent(MotionEvent event) {
-        final boolean isTouchHandleEvent = true;
-        return sendTouchEvent(event, isTouchHandleEvent);
+        return false;
     }
 
     private boolean sendTouchEvent(MotionEvent event, boolean isTouchHandleEvent) {
@@ -250,8 +262,9 @@
 
     /**
      * Sets the current amount to offset incoming touch events by (including MotionEvent and
-     * DragEvent). This is used to handle content moving and not lining up properly with the
-     * android input system.
+     * DragEvent). This is used to handle content moving and not lining up properly with the android
+     * input system.
+     *
      * @param dx The X offset in pixels to shift touch events.
      * @param dy The Y offset in pixels to shift touch events.
      */
@@ -261,8 +274,9 @@
     }
 
     /**
-     * Creates a new motion event differed from the given event by current touch offset
-     * if the offset is not zero.
+     * Creates a new motion event differed from the given event by current touch offset if the
+     * offset is not zero.
+     *
      * @param src Source motion event.
      * @return A new motion event if we have non-zero touch offset. Otherwise return the same event.
      */
@@ -345,8 +359,8 @@
     }
 
     /**
-     * Sends mouse event to native. Hover event is also converted to mouse event,
-     * only differentiated by an internal flag.
+     * Sends mouse event to native. Hover event is also converted to mouse event, only
+     * differentiated by an internal flag.
      */
     private boolean sendNativeMouseEvent(MotionEvent event) {
         assert mNativeEventForwarder != 0;
@@ -362,18 +376,20 @@
             // is provided using ACTION_MOVE touch events.
             return true;
         }
-
+        boolean shouldConvertToMouseEvent = isTrackpadToMouseEventConversionEnabled()
+                && isTrackpadClickOrClickAndDragEvent(event);
         EventForwarderJni.get().onMouseEvent(mNativeEventForwarder, EventForwarder.this,
                 MotionEventUtils.getEventTimeNano(event), eventAction, event.getX(), event.getY(),
                 event.getPointerId(0), event.getPressure(0), event.getOrientation(0),
                 event.getAxisValue(MotionEvent.AXIS_TILT, 0), getMouseEventActionButton(event),
-                event.getButtonState(), event.getMetaState(), event.getToolType(0));
+                event.getButtonState(), event.getMetaState(),
+                shouldConvertToMouseEvent ? MotionEvent.TOOL_TYPE_MOUSE : event.getToolType(0));
         return true;
     }
 
     /**
-     * Manages internal state to work around a device-specific issue. Needs to be called per
-     * every mouse event to update the state.
+     * Manages internal state to work around a device-specific issue. Needs to be called per every
+     * mouse event to update the state.
      */
     private void updateMouseEventState(MotionEvent event) {
         int eventAction = event.getActionMasked();
@@ -388,6 +404,36 @@
         return ApiHelperForM.getActionButton(event);
     }
 
+    public boolean isTrackpadToMouseEventConversionEnabled() {
+        return mConvertTrackpadEventsToMouse;
+    }
+
+    /**
+     * Returns true if a {@link MotionEvent} is a trackpad click and or click & drag event.
+     * Trackpad hover events and non-click gestures (i.e two-finger scroll) should return
+     * false here as they do have an action button pressed. Also we want to make sure we
+     * return true for button release events as well.
+     */
+    public static boolean isTrackpadClickOrClickAndDragEvent(MotionEvent event) {
+        return isTrackpadEvent(event)
+                && (event.getAction() == MotionEvent.ACTION_BUTTON_RELEASE
+                        || event.getButtonState() != 0);
+    }
+
+    /**
+     * Returns true if a {@link MotionEvent} is detected to be a trackpad event.
+     * Note that {@link MotionEvent.TOOL_TYPE_FINGER} is used here along with
+     * {@link InputDevice.SOURCE_MOUSE} instead of {@link InputDevice.SOURCE_TOUCHPAD}
+     * because {@link InputDevice.SOURCE_TOUCHPAD} is used when an app
+     * captures the touchpad meaning that it gets access to the raw finger locations,
+     * dimensions etc. reported by the touchpad rather than those being used for pointer movements
+     * and gestures.
+     */
+    private static boolean isTrackpadEvent(MotionEvent event) {
+        return event.isFromSource(InputDevice.SOURCE_MOUSE)
+                && event.getToolType(0) == MotionEvent.TOOL_TYPE_FINGER;
+    }
+
     /**
      * @see View#onDragEvent(DragEvent)
      * @param event {@link DragEvent} instance.
@@ -453,9 +499,8 @@
      *
      * @param type Type of the gesture event.
      * @param timeMs Time the event occurred in milliseconds.
-     * @param delta Scale factor for pinch gesture relative to the current state,
-     *        1.0 being 100%. If negative, has the effect of reverting
-     *        pinch scale to default.
+     * @param delta Scale factor for pinch gesture relative to the current state, 1.0 being 100%. If
+     *     negative, has the effect of reverting pinch scale to default.
      */
     public boolean onGestureEvent(@GestureEventType int type, long timeMs, float delta) {
         if (mNativeEventForwarder == 0) return false;
@@ -468,8 +513,11 @@
      */
     public boolean onGenericMotionEvent(MotionEvent event) {
         if (mNativeEventForwarder == 0) return false;
-        if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0
-                && event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) {
+        boolean isMouseEvent = (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0
+                && event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE;
+        boolean shouldConvertToMouseEvent = isTrackpadToMouseEventConversionEnabled()
+                && isTrackpadClickOrClickAndDragEvent(event);
+        if (isMouseEvent || shouldConvertToMouseEvent) {
             updateMouseEventState(event);
         }
 
@@ -519,13 +567,14 @@
 
     /**
      * Flings the viewport with velocity vector (velocityX, velocityY).
+     *
      * @param timeMs the current time.
      * @param velocityX fling speed in x-axis.
      * @param velocityY fling speed in y-axis.
      * @param syntheticScroll true if generated by gamepad (which will make this fixed-velocity
-     * fling)
+     *         fling)
      * @param preventBoost if false, this fling may boost an existing fling. Otherwise, ends the
-     * current fling and starts a new one.
+     *     current fling and starts a new one.
      */
     public void startFling(long timeMs, float velocityX, float velocityY, boolean syntheticScroll,
             boolean preventBoosting) {
@@ -536,6 +585,7 @@
 
     /**
      * Cancel any fling gestures active.
+     *
      * @param timeMs Current time (in milliseconds).
      */
     public void cancelFling(long timeMs) {
@@ -544,6 +594,7 @@
                 mNativeEventForwarder, EventForwarder.this, timeMs, /*preventBoosting*/ true);
     }
 
+    @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
     @NativeMethods
     interface Natives {
         WindowAndroid getJavaWindowAndroid(long nativeEventForwarder, EventForwarder caller);
@@ -559,20 +610,30 @@
         void onMouseEvent(long nativeEventForwarder, EventForwarder caller, long timeNs, int action,
                 float x, float y, int pointerId, float pressure, float orientation, float tilt,
                 int changedButton, int buttonState, int metaState, int toolType);
+
         void onDragEvent(long nativeEventForwarder, EventForwarder caller, int action, float x,
                 float y, float screenX, float screenY, String[] mimeTypes, String content);
+
         boolean onGestureEvent(long nativeEventForwarder, EventForwarder caller, int type,
                 long timeMs, float delta);
+
         boolean onGenericMotionEvent(
                 long nativeEventForwarder, EventForwarder caller, MotionEvent event, long timeNs);
+
         boolean onKeyUp(
                 long nativeEventForwarder, EventForwarder caller, KeyEvent event, int keyCode);
+
         boolean dispatchKeyEvent(long nativeEventForwarder, EventForwarder caller, KeyEvent event);
+
         void scrollBy(long nativeEventForwarder, EventForwarder caller, float deltaX, float deltaY);
+
         void scrollTo(long nativeEventForwarder, EventForwarder caller, float x, float y);
+
         void doubleTap(long nativeEventForwarder, EventForwarder caller, long timeMs, int x, int y);
+
         void startFling(long nativeEventForwarder, EventForwarder caller, long timeMs,
                 float velocityX, float velocityY, boolean syntheticScroll, boolean preventBoosting);
+
         void cancelFling(long nativeEventForwarder, EventForwarder caller, long timeMs,
                 boolean preventBoosting);
     }
diff --git a/ui/android/java/src/org/chromium/ui/base/UiAndroidFeatureList.java b/ui/android/java/src/org/chromium/ui/base/UiAndroidFeatureList.java
new file mode 100644
index 0000000..15732b1
--- /dev/null
+++ b/ui/android/java/src/org/chromium/ui/base/UiAndroidFeatureList.java
@@ -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.
+
+package org.chromium.ui.base;
+
+import org.chromium.base.annotations.JNINamespace;
+import org.chromium.base.annotations.NativeMethods;
+import org.chromium.build.annotations.MainDex;
+
+/**
+ * Java accessor for ui/android/ui_android_feature_list.cc state
+ */
+@JNINamespace("ui")
+@MainDex
+public class UiAndroidFeatureList {
+    // Do not instantiate this class
+    private UiAndroidFeatureList() {}
+
+    /**
+     * Returns whether the specified feature is enabled or not.
+     *
+     * Note: Features queried through this API must be added to the array
+     * |kFeaturesExposedToJava| in ui/android/ui_android_feature_list.cc
+     *
+     * @param featureName The name of the feature to query.
+     * @return Whether the feature is enabled or not.
+     */
+    public static boolean isEnabled(String featureName) {
+        return UiAndroidFeatureListJni.get().isEnabled(featureName);
+    }
+
+    @NativeMethods
+    public interface Natives {
+        boolean isEnabled(String featureName);
+    }
+}
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/OWNERS b/ui/android/java/src/org/chromium/ui/modelutil/OWNERS
index 38d75be..3a72bd0 100644
--- a/ui/android/java/src/org/chromium/ui/modelutil/OWNERS
+++ b/ui/android/java/src/org/chromium/ui/modelutil/OWNERS
@@ -1,2 +1,3 @@
+mdjones@chromium.org
 twellington@chromium.org
 tedchoc@chromium.org
diff --git a/ui/android/java_templates/UiAndroidFeatures.java.tmpl b/ui/android/java_templates/UiAndroidFeatures.java.tmpl
new file mode 100644
index 0000000..85eaa97
--- /dev/null
+++ b/ui/android/java_templates/UiAndroidFeatures.java.tmpl
@@ -0,0 +1,16 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.ui.base;
+
+/**
+ * Constants for the names of Ui Android Features.
+ */
+public final class UiAndroidFeatures {{
+
+{NATIVE_FEATURES}
+
+    // Do not instantiate this class.
+    private UiAndroidFeatures() {{}}
+}}
diff --git a/ui/android/junit/src/org/chromium/ui/base/EventForwarderTest.java b/ui/android/junit/src/org/chromium/ui/base/EventForwarderTest.java
new file mode 100644
index 0000000..dabc2df
--- /dev/null
+++ b/ui/android/junit/src/org/chromium/ui/base/EventForwarderTest.java
@@ -0,0 +1,171 @@
+// 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.ui.base;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyFloat;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.view.InputDevice;
+import android.view.MotionEvent;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.JniMocker;
+import org.chromium.ui.MotionEventUtils;
+
+/** Tests logic in the {@link EventForwarder} class. */
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class EventForwarderTest {
+    @Rule
+    public JniMocker mocker = new JniMocker();
+
+    @Mock
+    EventForwarder.Natives mNativeMock;
+
+    private static final long NATIVE_EVENT_FORWARDER_ID = 1;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mocker.mock(EventForwarderJni.TEST_HOOKS, mNativeMock);
+    }
+
+    @Test
+    public void testSendTrackpadClicksAsMouseEventToNative() {
+        EventForwarder eventForwarder = new EventForwarder(NATIVE_EVENT_FORWARDER_ID, true, true);
+
+        // Left click
+        MotionEvent leftClickEvent = getTrackpadLeftClickEvent();
+        eventForwarder.onTouchEvent(leftClickEvent);
+        verifyNativeMouseEventSent(NATIVE_EVENT_FORWARDER_ID, leftClickEvent, eventForwarder, 1);
+
+        // Right click
+        MotionEvent rightClickEvent = getTrackRightClickEvent();
+        eventForwarder.onTouchEvent(rightClickEvent);
+        verifyNativeMouseEventSent(NATIVE_EVENT_FORWARDER_ID, rightClickEvent, eventForwarder, 1);
+    }
+
+    @Test
+    public void testSendTrackpadClickReleaseAsMouseEventToNative() {
+        EventForwarder eventForwarder = new EventForwarder(NATIVE_EVENT_FORWARDER_ID, true, true);
+
+        // Left click
+        MotionEvent leftClickReleaseEvent =
+                getTrackpadEvent(MotionEvent.ACTION_BUTTON_RELEASE, MotionEvent.BUTTON_PRIMARY);
+        eventForwarder.onTouchEvent(leftClickReleaseEvent);
+        verifyNativeMouseEventSent(
+                NATIVE_EVENT_FORWARDER_ID, leftClickReleaseEvent, eventForwarder, 1);
+
+        // Right click
+        MotionEvent rightClickReleaseEvent =
+                getTrackpadEvent(MotionEvent.ACTION_BUTTON_RELEASE, MotionEvent.BUTTON_SECONDARY);
+        eventForwarder.onTouchEvent(rightClickReleaseEvent);
+        verifyNativeMouseEventSent(
+                NATIVE_EVENT_FORWARDER_ID, rightClickReleaseEvent, eventForwarder, 1);
+    }
+
+    @Test
+    public void testSendTrackpadClickAndDragAsMouseEventToNative() {
+        EventForwarder eventForwarder = new EventForwarder(NATIVE_EVENT_FORWARDER_ID, true, true);
+        MotionEvent clickAndDragEvent =
+                getTrackpadEvent(MotionEvent.ACTION_MOVE, MotionEvent.BUTTON_PRIMARY);
+        eventForwarder.onTouchEvent(clickAndDragEvent);
+        verifyNativeMouseEventSent(NATIVE_EVENT_FORWARDER_ID, clickAndDragEvent, eventForwarder, 1);
+    }
+
+    @Test
+    public void testSendTrackEventAsTouchEventWhenButtonIsNotClicked() {
+        EventForwarder eventForwarder = new EventForwarder(NATIVE_EVENT_FORWARDER_ID, true, true);
+        MotionEvent trackpadTouchDownEventNoClick = getTrackpadTouchDownEventNoClick();
+        eventForwarder.onTouchEvent(trackpadTouchDownEventNoClick);
+        verify(mNativeMock, times(1))
+                .onTouchEvent(anyLong(), any(EventForwarder.class), any(MotionEvent.class),
+                        anyLong(), anyInt(), anyInt(), anyInt(), anyInt(), anyFloat(), anyFloat(),
+                        anyFloat(), anyFloat(), anyInt(), anyInt(), anyFloat(), anyFloat(),
+                        anyFloat(), anyFloat(), anyFloat(), anyFloat(), anyFloat(), anyFloat(),
+                        anyFloat(), anyFloat(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(),
+                        anyBoolean());
+        verify(mNativeMock, never())
+                .onMouseEvent(anyLong(), any(EventForwarder.class), anyLong(), anyInt(), anyFloat(),
+                        anyFloat(), anyInt(), anyFloat(), anyFloat(), anyFloat(), anyInt(),
+                        anyInt(), anyInt(), anyInt());
+    }
+
+    @Test
+    public void testNotSendTrackpadClickAsMouseEventWhenFeatureDisabled() {
+        EventForwarder eventForwarder = new EventForwarder(NATIVE_EVENT_FORWARDER_ID, true, false);
+        MotionEvent trackpadClickDownEvent = getTrackpadLeftClickEvent();
+        eventForwarder.onTouchEvent(trackpadClickDownEvent);
+        verify(mNativeMock, never())
+                .onMouseEvent(anyLong(), any(EventForwarder.class), anyLong(), anyInt(), anyFloat(),
+                        anyFloat(), anyInt(), anyFloat(), anyFloat(), anyFloat(), anyInt(),
+                        anyInt(), anyInt(), anyInt());
+    }
+
+    private void verifyNativeMouseEventSent(long nativeEventForwarder, MotionEvent event,
+            EventForwarder eventForwarder, int times) {
+        verify(mNativeMock, times(times))
+                .onMouseEvent(nativeEventForwarder, eventForwarder,
+                        MotionEventUtils.getEventTimeNano(event), event.getActionMasked(),
+                        event.getX(), event.getY(), event.getPointerId(0), event.getPressure(0),
+                        event.getOrientation(0), event.getAxisValue(MotionEvent.AXIS_TILT, 0),
+                        EventForwarder.getMouseEventActionButton(event), event.getButtonState(),
+                        event.getMetaState(), MotionEvent.TOOL_TYPE_MOUSE);
+    }
+
+    private static MotionEvent getTrackpadTouchDownEventNoClick() {
+        return getTrackpadEvent(MotionEvent.ACTION_DOWN, 0);
+    }
+
+    private static MotionEvent getTrackpadLeftClickEvent() {
+        return getTrackpadEvent(MotionEvent.ACTION_BUTTON_PRESS, MotionEvent.BUTTON_PRIMARY);
+    }
+
+    private static MotionEvent getTrackRightClickEvent() {
+        return getTrackpadEvent(MotionEvent.ACTION_BUTTON_PRESS, MotionEvent.BUTTON_SECONDARY);
+    }
+
+    private static MotionEvent getTrackpadEvent(int action, int buttonState) {
+        return MotionEvent.obtain(0, 0, action, 1, getToolTypeFingerProperties(),
+                getPointerCoords(), 0, buttonState, 0, 0, 0, 0, getTrackpadSource(), 0);
+    }
+
+    private static MotionEvent.PointerProperties[] getToolTypeFingerProperties() {
+        MotionEvent.PointerProperties[] pointerPropertiesArray =
+                new MotionEvent.PointerProperties[1];
+        MotionEvent.PointerProperties trackpadProperties = new MotionEvent.PointerProperties();
+        trackpadProperties.id = 7;
+        trackpadProperties.toolType = MotionEvent.TOOL_TYPE_FINGER;
+        pointerPropertiesArray[0] = trackpadProperties;
+        return pointerPropertiesArray;
+    }
+
+    private static MotionEvent.PointerCoords[] getPointerCoords() {
+        MotionEvent.PointerCoords[] pointerCoordsArray = new MotionEvent.PointerCoords[1];
+        MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords();
+        coords.x = 14;
+        coords.y = 21;
+        pointerCoordsArray[0] = coords;
+        return pointerCoordsArray;
+    }
+
+    private static int getTrackpadSource() {
+        return InputDevice.SOURCE_MOUSE;
+    }
+}
diff --git a/ui/android/junit/src/org/chromium/ui/modelutil/OWNERS b/ui/android/junit/src/org/chromium/ui/modelutil/OWNERS
new file mode 100644
index 0000000..7cf54c2
--- /dev/null
+++ b/ui/android/junit/src/org/chromium/ui/modelutil/OWNERS
@@ -0,0 +1 @@
+file://ui/android/java/src/org/chromium/ui/modelutil/OWNERS
diff --git a/ui/android/ui_android_feature_list.cc b/ui/android/ui_android_feature_list.cc
new file mode 100644
index 0000000..5a2857a
--- /dev/null
+++ b/ui/android/ui_android_feature_list.cc
@@ -0,0 +1,46 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/android/jni_string.h"
+#include "base/feature_list.h"
+#include "base/notreached.h"
+#include "ui/android/ui_android_features.h"
+#include "ui/android/ui_android_jni_headers/UiAndroidFeatureList_jni.h"
+
+using base::android::ConvertJavaStringToUTF8;
+using base::android::JavaParamRef;
+
+namespace ui {
+
+namespace {
+
+// Array of features exposed through the Java AwFeatureList API. Entries in
+// this array may either refer to features defined in the header of this file or
+// in other locations in the code base (e.g. content/, components/, etc).
+const base::Feature* const kFeaturesExposedToJava[] = {
+    &features::kConvertTrackpadEventsToMouse,
+};
+
+const base::Feature* FindFeatureExposedToJava(const std::string& feature_name) {
+  for (const base::Feature* feature : kFeaturesExposedToJava) {
+    if (feature->name == feature_name) {
+      return feature;
+    }
+  }
+  NOTREACHED() << "Queried feature cannot be found in UiAndroidFeatureList: "
+               << feature_name;
+  return nullptr;
+}
+
+}  // namespace
+
+static jboolean JNI_UiAndroidFeatureList_IsEnabled(
+    JNIEnv* env,
+    const JavaParamRef<jstring>& jfeature_name) {
+  const base::Feature* feature =
+      FindFeatureExposedToJava(ConvertJavaStringToUTF8(env, jfeature_name));
+  return base::FeatureList::IsEnabled(*feature);
+}
+
+}  // namespace ui
diff --git a/ui/android/ui_android_features.cc b/ui/android/ui_android_features.cc
new file mode 100644
index 0000000..4749b96e
--- /dev/null
+++ b/ui/android/ui_android_features.cc
@@ -0,0 +1,13 @@
+// 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/android/ui_android_features.h"
+
+#include "base/feature_list.h"
+
+namespace features {
+BASE_FEATURE(kConvertTrackpadEventsToMouse,
+             "ConvertTrackpadEventsToMouse",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+}  // namespace features
diff --git a/ui/android/ui_android_features.h b/ui/android/ui_android_features.h
new file mode 100644
index 0000000..c74cbe8
--- /dev/null
+++ b/ui/android/ui_android_features.h
@@ -0,0 +1,22 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_ANDROID_UI_ANDROID_FEATURES_H_
+#define UI_ANDROID_UI_ANDROID_FEATURES_H_
+
+#include "base/component_export.h"
+#include "base/feature_list.h"
+
+namespace features {
+
+// Keep sorted!
+
+// Enables converting trackpad click gestures to mouse events in
+// order for them to be interpreted similar to a desktop
+// experience (i.e. double-click to select word.)
+COMPONENT_EXPORT(UI_ANDROID_FEATURES)
+BASE_DECLARE_FEATURE(kConvertTrackpadEventsToMouse);
+}  // namespace features
+
+#endif  // UI_ANDROID_UI_ANDROID_FEATURES_H_
diff --git a/ui/base/mojom/attributed_string.mojom b/ui/base/mojom/attributed_string.mojom
index 41fe5be..2807049d 100644
--- a/ui/base/mojom/attributed_string.mojom
+++ b/ui/base/mojom/attributed_string.mojom
@@ -7,22 +7,21 @@
 import "mojo/public/mojom/base/string16.mojom";
 import "ui/gfx/range/mojom/range.mojom";
 
-// This will serialize the font information of an NSAttributedString so that
-// it can be sent over mojo. This only stores the information of the
-// NSFontAttributeName. The motive is that of security: using NSArchiver and
-// friends to send objects from the renderer to the browser could lead to
-// deserialization of arbitrary objects. This restricts serialization to a
-// specific object class and specific attributes of that object.
+// This will serialize the font information of a CFAttributedString so that it
+// can be sent over mojo. This only stores the information of the font name and
+// font size. The motive is that of security: using NSArchiver and friends to
+// send objects from the renderer to the browser could lead to deserialization
+// of arbitrary objects. This restricts serialization to a specific object class
+// and specific attributes of that object.
 
-// A C++ mojo-friendly representation of the NSFontAttributeName attribute
-// set.
+// A C++ mojo-friendly representation of the font and font size attribute set.
 struct FontAttribute {
   mojo_base.mojom.String16 font_name;
   float font_point_size;
   gfx.mojom.Range effective_range;
 };
 
-// A struct that contains the pertinent information from an NSAttributedString,
+// A struct that contains the pertinent information from a CFAttributedString,
 // which can be serialized over mojo.
 struct AttributedString {
   // The plain-text string.
diff --git a/ui/display/display_util.cc b/ui/display/display_util.cc
index f6a1cb0..81c0bf9 100644
--- a/ui/display/display_util.cc
+++ b/ui/display/display_util.cc
@@ -41,7 +41,7 @@
     screen_info->orientation_angle = 90;
 #endif
 
-#if BUILDFLAG(IS_ANDROID)
+#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
   screen_info->orientation_type = GetOrientationTypeForMobile(display);
 #else
   screen_info->orientation_type = GetOrientationTypeForDesktop(display);
diff --git a/ui/gfx/native_widget_types.h b/ui/gfx/native_widget_types.h
index 1108473a..682c22c5 100644
--- a/ui/gfx/native_widget_types.h
+++ b/ui/gfx/native_widget_types.h
@@ -13,10 +13,7 @@
 
 #if BUILDFLAG(IS_ANDROID)
 #include "base/android/scoped_java_ref.h"
-#elif BUILDFLAG(IS_IOS)
-#include <objc/objc.h>
 #elif BUILDFLAG(IS_MAC)
-#include <objc/objc.h>
 #include <string>
 #elif BUILDFLAG(IS_WIN)
 #include "base/win/windows_types.h"
@@ -63,6 +60,7 @@
 #elif BUILDFLAG(IS_IOS)
 struct CGContext;
 #ifdef __OBJC__
+struct objc_object;
 @class UIEvent;
 @class UIFont;
 @class UIImage;
@@ -88,6 +86,7 @@
 @class NSWindow;
 @class NSTextField;
 #else
+struct objc_object;
 class NSCursor;
 class NSEvent;
 class NSFont;
@@ -140,8 +139,6 @@
 // function call (GetNativeNSView or GetNativeNSWindow) to retrieve the
 // underlying NSView or NSWindow <https://crbug.com/893719>. These are wrapper
 // classes only and do not maintain any ownership, thus the __unsafe_unretained.
-// (__unsafe_unretained is defined in <objc/objc.h> for non-Obj-C so it's OK to
-// use in C++ code.)
 class GFX_EXPORT NativeView {
  public:
   constexpr NativeView() = default;
@@ -153,7 +150,7 @@
   // is easily grep-able.
   NSView* GetNativeNSView() const { return ns_view_; }
 
-  explicit operator bool() const { return ns_view_ != nil; }
+  explicit operator bool() const { return ns_view_ != nullptr; }
   bool operator==(const NativeView& other) const {
     return ns_view_ == other.ns_view_;
   }
@@ -166,7 +163,11 @@
   std::string ToString() const;
 
  private:
-  __unsafe_unretained NSView* ns_view_ = nil;
+#if defined(__has_feature) && __has_feature(objc_arc)
+  __unsafe_unretained NSView* ns_view_ = nullptr;
+#else
+  NSView* ns_view_ = nullptr;
+#endif
 };
 class GFX_EXPORT NativeWindow {
  public:
@@ -179,7 +180,7 @@
   // is easily grep-able.
   NSWindow* GetNativeNSWindow() const { return ns_window_; }
 
-  explicit operator bool() const { return ns_window_ != nil; }
+  explicit operator bool() const { return ns_window_ != nullptr; }
   bool operator==(const NativeWindow& other) const {
     return ns_window_ == other.ns_window_;
   }
@@ -192,7 +193,11 @@
   std::string ToString() const;
 
  private:
-  __unsafe_unretained NSWindow* ns_window_ = nil;
+#if defined(__has_feature) && __has_feature(objc_arc)
+  __unsafe_unretained NSWindow* ns_window_ = nullptr;
+#else
+  NSWindow* ns_window_ = nullptr;
+#endif
 };
 constexpr NativeView kNullNativeView = NativeView(nullptr);
 constexpr NativeWindow kNullNativeWindow = NativeWindow(nullptr);
@@ -212,10 +217,18 @@
 using NativeViewAccessible = IAccessible*;
 #elif BUILDFLAG(IS_IOS)
 using NativeFont = UIFont*;
+#ifdef __OBJC__
 using NativeViewAccessible = id;
+#else
+using NativeViewAccessible = struct objc_object*;
+#endif
 #elif BUILDFLAG(IS_MAC)
 using NativeFont = NSFont*;
+#ifdef __OBJC__
 using NativeViewAccessible = id;
+#else
+using NativeViewAccessible = struct objc_object*;
+#endif
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
 #elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/ui/gfx/x/gen_xproto.py b/ui/gfx/x/gen_xproto.py
index 6986842..e5a71190 100644
--- a/ui/gfx/x/gen_xproto.py
+++ b/ui/gfx/x/gen_xproto.py
@@ -1544,7 +1544,7 @@
             self.write()
             for name, event, proto in self.events:
                 self.gen_event(name, event, proto)
-            self.write('NOTREACHED();')
+            self.write('// Leave `event` default-initialized.')
         self.write()
         self.write('}  // namespace x11')
 
diff --git a/ui/gfx/x/generated_protos/read_event.cc b/ui/gfx/x/generated_protos/read_event.cc
index b9827997..8b7466d4 100644
--- a/ui/gfx/x/generated_protos/read_event.cc
+++ b/ui/gfx/x/generated_protos/read_event.cc
@@ -1372,7 +1372,7 @@
     return;
   }
 
-  NOTREACHED();
+  // Leave `event` default-initialized.
 }
 
 }  // namespace x11
diff --git a/ui/ozone/platform/wayland/fuzzer/wayland_buffer_fuzzer.cc b/ui/ozone/platform/wayland/fuzzer/wayland_buffer_fuzzer.cc
index c1c6c81..d954c17d 100644
--- a/ui/ozone/platform/wayland/fuzzer/wayland_buffer_fuzzer.cc
+++ b/ui/ozone/platform/wayland/fuzzer/wayland_buffer_fuzzer.cc
@@ -118,7 +118,7 @@
       DRM_FORMAT_NV12,        DRM_FORMAT_YVU420};
 
   wl::TestWaylandServerThread server;
-  CHECK(server.Start({}));
+  CHECK(server.Start());
 
   std::unique_ptr<ui::WaylandConnection> connection =
       std::make_unique<ui::WaylandConnection>();
diff --git a/ui/ozone/platform/wayland/gpu/wayland_surface_factory_unittest.cc b/ui/ozone/platform/wayland/gpu/wayland_surface_factory_unittest.cc
index 681b417..b357a0b 100644
--- a/ui/ozone/platform/wayland/gpu/wayland_surface_factory_unittest.cc
+++ b/ui/ozone/platform/wayland/gpu/wayland_surface_factory_unittest.cc
@@ -1454,6 +1454,7 @@
 INSTANTIATE_TEST_SUITE_P(
     CompositorVersionV3Test,
     WaylandSurfaceFactoryCompositorV3,
-    Values(wl::ServerConfig{.compositor_version = wl::CompositorVersion::kV3}));
+    Values(wl::ServerConfig{
+        .compositor_version = wl::TestCompositor::Version::kV3}));
 
 }  // namespace ui
diff --git a/ui/ozone/platform/wayland/host/wayland_connection_unittest.cc b/ui/ozone/platform/wayland/host/wayland_connection_unittest.cc
index d4332e98..c7b6d591 100644
--- a/ui/ozone/platform/wayland/host/wayland_connection_unittest.cc
+++ b/ui/ozone/platform/wayland/host/wayland_connection_unittest.cc
@@ -27,15 +27,8 @@
 
 TEST_P(WaylandConnectionTest, CompositorVersionTest) {
   wl::ServerConfig config = GetParam();
-  uint32_t expected_compositor_version = 0;
-  switch (config.compositor_version) {
-    case wl::CompositorVersion::kV3:
-      expected_compositor_version = 3;
-      break;
-    case wl::CompositorVersion::kV4:
-      expected_compositor_version = 4;
-      break;
-  }
+  uint32_t expected_compositor_version =
+      static_cast<uint32_t>(config.compositor_version);
 
   EXPECT_EQ(expected_compositor_version,
             wl::get_version_of_object(connection_->compositor()));
@@ -44,10 +37,12 @@
 INSTANTIATE_TEST_SUITE_P(
     XdgVersionStableTest,
     WaylandConnectionTest,
-    Values(wl::ServerConfig{.compositor_version = wl::CompositorVersion::kV3}));
+    Values(wl::ServerConfig{
+        .compositor_version = wl::TestCompositor::Version::kV3}));
 INSTANTIATE_TEST_SUITE_P(
     XdgVersionStableTestCompositorV4,
     WaylandConnectionTest,
-    Values(wl::ServerConfig{.compositor_version = wl::CompositorVersion::kV4}));
+    Values(wl::ServerConfig{
+        .compositor_version = wl::TestCompositor::Version::kV4}));
 
 }  // namespace ui
diff --git a/ui/ozone/platform/wayland/host/wayland_output_unittest.cc b/ui/ozone/platform/wayland/host/wayland_output_unittest.cc
index 5b88d18..97cff7edd 100644
--- a/ui/ozone/platform/wayland/host/wayland_output_unittest.cc
+++ b/ui/ozone/platform/wayland/host/wayland_output_unittest.cc
@@ -8,6 +8,7 @@
 #include "ui/base/wayland/wayland_display_util.h"
 #include "ui/ozone/platform/wayland/host/wayland_output_manager.h"
 #include "ui/ozone/platform/wayland/host/xdg_output.h"
+#include "ui/ozone/platform/wayland/test/test_wayland_server_thread.h"
 #include "ui/ozone/platform/wayland/test/wayland_test.h"
 
 using ::testing::Values;
@@ -138,14 +139,12 @@
   EXPECT_TRUE(new_output->IsReady());
 }
 
-class WaylandOutpuWithAuraOutputManagerTest
-    : public WaylandTestSimpleWithAuraShell {
+class WaylandOutputWithAuraOutputManagerTest : public WaylandTestSimple {
  protected:
-  // WaylandTestSimpleWithAuraShell:
-  void SetUp() override {
-    SetUseAuraOutputManager(true);
-    WaylandTestSimpleWithAuraShell::SetUp();
-  }
+  WaylandOutputWithAuraOutputManagerTest()
+      : WaylandTestSimple(wl::ServerConfig{
+            .enable_aura_shell = wl::EnableAuraShellProtocol::kEnabled,
+            .use_aura_output_manager = true}) {}
 
   WaylandOutputManager* wayland_output_manager() {
     auto* wayland_output_manager = connection_->wayland_output_manager();
@@ -160,7 +159,7 @@
 
 // Tests that WaylandOutput only reports as ready if metrics has been set when
 // the aura output manager is bound.
-TEST_F(WaylandOutpuWithAuraOutputManagerTest, WaylandOutputIsReady) {
+TEST_F(WaylandOutputWithAuraOutputManagerTest, WaylandOutputIsReady) {
   auto* output_manager = connection_->wayland_output_manager();
   const auto* primary_output = output_manager->GetPrimaryOutput();
 
@@ -197,7 +196,8 @@
 // Tests that delegate notifications are not triggered when the wl_output.done
 // event is received. It is instead expected to be triggered by the aura output
 // manager.
-TEST_F(WaylandOutpuWithAuraOutputManagerTest, SuppressesDelegateNotifications) {
+TEST_F(WaylandOutputWithAuraOutputManagerTest,
+       SuppressesDelegateNotifications) {
   testing::NiceMock<MockWaylandOutputDelegate> output_delegate;
   EXPECT_CALL(output_delegate, OnOutputHandleMetrics(testing::_)).Times(0);
   primary_output()->set_delegate_for_testing(&output_delegate);
diff --git a/ui/ozone/platform/wayland/host/wayland_zaura_output_manager_unittest.cc b/ui/ozone/platform/wayland/host/wayland_zaura_output_manager_unittest.cc
index 957208f..55194ee 100644
--- a/ui/ozone/platform/wayland/host/wayland_zaura_output_manager_unittest.cc
+++ b/ui/ozone/platform/wayland/host/wayland_zaura_output_manager_unittest.cc
@@ -45,14 +45,14 @@
 
 }  // namespace
 
-class WaylandZAuraOutputManagerTest : public WaylandTestSimpleWithAuraShell {
- protected:
-  // WaylandTestSimpleWithAuraShell:
-  void SetUp() override {
-    SetUseAuraOutputManager(true);
-    WaylandTestSimpleWithAuraShell::SetUp();
-  }
+class WaylandZAuraOutputManagerTest : public WaylandTestSimple {
+ public:
+  WaylandZAuraOutputManagerTest()
+      : WaylandTestSimple(wl::ServerConfig{
+            .enable_aura_shell = wl::EnableAuraShellProtocol::kEnabled,
+            .use_aura_output_manager = true}) {}
 
+ protected:
   // Sends sample metrics to the primary output configured for this fixture.
   void SendSampleMetrics(const WaylandOutput::Metrics& metrics) {
     const auto wayland_display_id =
diff --git a/ui/ozone/platform/wayland/test/test_compositor.cc b/ui/ozone/platform/wayland/test/test_compositor.cc
index 4e0b306..f70043a 100644
--- a/ui/ozone/platform/wayland/test/test_compositor.cc
+++ b/ui/ozone/platform/wayland/test/test_compositor.cc
@@ -39,10 +39,10 @@
     CreateRegion,   // create_region
 };
 
-TestCompositor::TestCompositor(uint32_t intended_version)
+TestCompositor::TestCompositor(TestCompositor::Version intended_version)
     : GlobalObject(&wl_compositor_interface,
                    &kTestCompositorImpl,
-                   intended_version),
+                   static_cast<uint32_t>(intended_version)),
       version_(intended_version) {}
 
 TestCompositor::~TestCompositor() = default;
diff --git a/ui/ozone/platform/wayland/test/test_compositor.h b/ui/ozone/platform/wayland/test/test_compositor.h
index 8e2e7b8..24d18d0 100644
--- a/ui/ozone/platform/wayland/test/test_compositor.h
+++ b/ui/ozone/platform/wayland/test/test_compositor.h
@@ -5,6 +5,7 @@
 #ifndef UI_OZONE_PLATFORM_WAYLAND_TEST_TEST_COMPOSITOR_H_
 #define UI_OZONE_PLATFORM_WAYLAND_TEST_TEST_COMPOSITOR_H_
 
+#include <cstdint>
 #include <vector>
 
 #include "ui/ozone/platform/wayland/test/global_object.h"
@@ -16,7 +17,11 @@
 // Manage wl_compositor object.
 class TestCompositor : public GlobalObject {
  public:
-  explicit TestCompositor(uint32_t intended_version);
+  enum class Version : uint32_t {
+    kV3 = 3,
+    kV4 = 4,
+  };
+  explicit TestCompositor(Version intended_version);
 
   TestCompositor(const TestCompositor&) = delete;
   TestCompositor& operator=(const TestCompositor&) = delete;
@@ -24,10 +29,10 @@
   ~TestCompositor() override;
 
   void AddSurface(MockSurface* surface);
-  uint32_t GetVersion() { return version_; }
+  Version GetVersion() { return version_; }
 
  private:
-  uint32_t version_;
+  Version version_;
   std::vector<MockSurface*> surfaces_;
 };
 
diff --git a/ui/ozone/platform/wayland/test/test_wayland_server_thread.cc b/ui/ozone/platform/wayland/test/test_wayland_server_thread.cc
index 6e7e5df..b61a5174 100644
--- a/ui/ozone/platform/wayland/test/test_wayland_server_thread.cc
+++ b/ui/ozone/platform/wayland/test/test_wayland_server_thread.cc
@@ -43,10 +43,13 @@
 }
 
 TestWaylandServerThread::TestWaylandServerThread()
+    : TestWaylandServerThread(ServerConfig{}) {}
+
+TestWaylandServerThread::TestWaylandServerThread(const ServerConfig& config)
     : Thread("test_wayland_server"),
       client_destroy_listener_(this),
-      compositor_v4_(4),
-      compositor_v3_(3),
+      config_(config),
+      compositor_(config.compositor_version),
       output_(base::BindRepeating(
           &TestWaylandServerThread::OnTestOutputMetricsFlush,
           base::Unretained(this))),
@@ -81,7 +84,7 @@
   client_ = nullptr;
 }
 
-bool TestWaylandServerThread::Start(const ServerConfig& config) {
+bool TestWaylandServerThread::Start() {
   display_.reset(wl_display_create());
   if (!display_)
     return false;
@@ -95,12 +98,8 @@
 
   if (wl_display_init_shm(display_.get()) < 0)
     return false;
-  if (config.compositor_version == CompositorVersion::kV3) {
-    if (!compositor_v3_.Initialize(display_.get()))
-      return false;
-  } else {
-    if (!compositor_v4_.Initialize(display_.get()))
-      return false;
+  if (!compositor_.Initialize(display_.get())) {
+    return false;
   }
   if (!sub_compositor_.Initialize(display_.get()))
     return false;
@@ -109,8 +108,8 @@
   if (!alpha_compositing_.Initialize(display_.get()))
     return false;
 
-  if (config.enable_aura_shell == EnableAuraShellProtocol::kEnabled) {
-    if (config.use_aura_output_manager) {
+  if (config_.enable_aura_shell == EnableAuraShellProtocol::kEnabled) {
+    if (config_.use_aura_output_manager) {
       // zaura_output_manager should be initialized before any wl_output
       // globals.
       if (!zaura_output_manager_.Initialize(display_.get())) {
@@ -133,8 +132,9 @@
 
   if (!data_device_manager_.Initialize(display_.get()))
     return false;
-  if (!SetupPrimarySelectionManager(config.primary_selection_protocol))
+  if (!SetupPrimarySelectionManager(config_.primary_selection_protocol)) {
     return false;
+  }
 
   if (!seat_.Initialize(display_.get()))
     return false;
@@ -145,7 +145,7 @@
   if (!zcr_stylus_.Initialize(display_.get()))
     return false;
 
-  switch (config.text_input_extension_version) {
+  switch (config_.text_input_extension_version) {
     case TextInputExtensionVersion::kV7:
       zcr_text_input_extension_v1_ =
           std::make_unique<TestZcrTextInputExtensionV1>(7);
@@ -162,8 +162,9 @@
   if (!zwp_text_input_manager_v1_.Initialize(display_.get()))
     return false;
   if (!SetupExplicitSynchronizationProtocol(
-          config.use_explicit_synchronization))
+          config_.use_explicit_synchronization)) {
     return false;
+  }
   if (!zwp_linux_dmabuf_v1_.Initialize(display_.get()))
     return false;
   if (!overlay_prioritizer_.Initialize(display_.get()))
diff --git a/ui/ozone/platform/wayland/test/test_wayland_server_thread.h b/ui/ozone/platform/wayland/test/test_wayland_server_thread.h
index 8771fbb..d5e9b75c 100644
--- a/ui/ozone/platform/wayland/test/test_wayland_server_thread.h
+++ b/ui/ozone/platform/wayland/test/test_wayland_server_thread.h
@@ -53,7 +53,6 @@
 
 // Server configuration related enums and structs.
 enum class PrimarySelectionProtocol { kNone, kGtk, kZwp };
-enum class CompositorVersion { kV3, kV4 };
 enum class TextInputExtensionVersion { kV7, kV8 };
 enum class ShouldUseExplicitSynchronizationProtocol { kNone, kUse };
 enum class EnableAuraShellProtocol { kEnabled, kDisabled };
@@ -61,7 +60,7 @@
 struct ServerConfig {
   TextInputExtensionVersion text_input_extension_version =
       TextInputExtensionVersion::kV8;
-  CompositorVersion compositor_version = CompositorVersion::kV4;
+  TestCompositor::Version compositor_version = TestCompositor::Version::kV4;
   PrimarySelectionProtocol primary_selection_protocol =
       PrimarySelectionProtocol::kNone;
   ShouldUseExplicitSynchronizationProtocol use_explicit_synchronization =
@@ -91,6 +90,7 @@
   class OutputDelegate;
 
   TestWaylandServerThread();
+  explicit TestWaylandServerThread(const ServerConfig& config);
 
   TestWaylandServerThread(const TestWaylandServerThread&) = delete;
   TestWaylandServerThread& operator=(const TestWaylandServerThread&) = delete;
@@ -102,9 +102,7 @@
   // descriptor that a client can connect to. The caller is responsible for
   // ensuring that this file descriptor gets closed (for example, by calling
   // wl_display_connect).
-  // Instantiates an xdg_shell of version |shell_version|; versions 6 and 7
-  // (stable) are supported.
-  bool Start(const ServerConfig& config);
+  bool Start();
 
   // Runs 'callback' or 'closure' on the server thread; blocks until the
   // callable is run and all pending Wayland requests and events are delivered.
@@ -225,13 +223,11 @@
   raw_ptr<wl_event_loop> event_loop_ = nullptr;
   raw_ptr<wl_protocol_logger> protocol_logger_ = nullptr;
 
+  ServerConfig config_;
+
   // Represent Wayland global objects
-  // Compositor version is selected dynamically by server config but version is
-  // actually set on construction thus both compositor version objects appear
-  // here.
-  // TODO(crbug.com/1315587): Refactor this pattern when required.
-  TestCompositor compositor_v4_;
-  TestCompositor compositor_v3_;
+  TestCompositor compositor_;
+
   TestSubCompositor sub_compositor_;
   TestViewporter viewporter_;
   TestAlphaCompositing alpha_compositing_;
diff --git a/ui/ozone/platform/wayland/test/wayland_test.cc b/ui/ozone/platform/wayland/test/wayland_test.cc
index a2bd1d9..3b692e1 100644
--- a/ui/ozone/platform/wayland/test/wayland_test.cc
+++ b/ui/ozone/platform/wayland/test/wayland_test.cc
@@ -36,7 +36,7 @@
 WaylandTestBase::WaylandTestBase(wl::ServerConfig config)
     : task_environment_(base::test::TaskEnvironment::MainThreadType::UI,
                         base::test::TaskEnvironment::TimeSource::MOCK_TIME),
-      config_(config) {
+      server_(config) {
 #if BUILDFLAG(USE_XKBCOMMON)
   auto keyboard_layout_engine =
       std::make_unique<XkbKeyboardLayoutEngine>(xkb_evdev_code_converter_);
@@ -66,7 +66,7 @@
     DeviceDataManager::CreateInstance();
   }
 
-  ASSERT_TRUE(server_.Start(config_));
+  ASSERT_TRUE(server_.Start());
   ASSERT_TRUE(connection_->Initialize());
   screen_ = connection_->wayland_output_manager()->CreateWaylandScreen();
   connection_->wayland_output_manager()->InitWaylandScreen(screen_.get());
@@ -122,13 +122,6 @@
   wl::SyncDisplay(connection_->display_wrapper(), *connection_->display());
 }
 
-void WaylandTestBase::SetUseAuraOutputManager(bool use_aura_output_manager) {
-  // Must be called before the test server is started and the global display has
-  // been created.
-  DCHECK(!server_.display());
-  config_.use_aura_output_manager = use_aura_output_manager;
-}
-
 void WaylandTestBase::DisableSyncOnTearDown() {
   initialized_ = false;
 }
diff --git a/ui/ozone/platform/wayland/test/wayland_test.h b/ui/ozone/platform/wayland/test/wayland_test.h
index 88b92981..02acdf2 100644
--- a/ui/ozone/platform/wayland/test/wayland_test.h
+++ b/ui/ozone/platform/wayland/test/wayland_test.h
@@ -64,10 +64,6 @@
   }
 
  protected:
-  // Sets the test server `config_` to use the zaura_output_manager global. This
-  // must be called before WaylandTestBase::SetUp().
-  void SetUseAuraOutputManager(bool use_aura_output_manager);
-
   // Disables client-server sync during the teardown.  Used by tests that
   // intentionally spoil the client-server communication.
   void DisableSyncOnTearDown();
@@ -133,8 +129,6 @@
 
   std::unique_ptr<KeyboardLayoutEngine> keyboard_layout_engine_;
   base::test::ScopedFeatureList feature_list_;
-
-  wl::ServerConfig config_;
 };
 
 // Version of WaylandTestBase that uses parametrised tests (TEST_P).
diff --git a/ui/views/controls/button/image_button.cc b/ui/views/controls/button/image_button.cc
index 9e87c2c4..9e5d6736 100644
--- a/ui/views/controls/button/image_button.cc
+++ b/ui/views/controls/button/image_button.cc
@@ -40,6 +40,7 @@
   // implementation is flipped horizontally so that the button's images are
   // mirrored when the UI directionality is right-to-left.
   SetFlipCanvasOnPaintForRTLUI(true);
+  views::FocusRing::Get(this)->SetOutsetFocusRingDisabled(true);
 }
 
 ImageButton::~ImageButton() = default;
diff --git a/ui/views/controls/button/radio_button.cc b/ui/views/controls/button/radio_button.cc
index 4b61c2d1..a570846e 100644
--- a/ui/views/controls/button/radio_button.cc
+++ b/ui/views/controls/button/radio_button.cc
@@ -33,6 +33,7 @@
 RadioButton::RadioButton(const std::u16string& label, int group_id)
     : Checkbox(label) {
   SetGroup(group_id);
+  views::FocusRing::Get(this)->SetOutsetFocusRingDisabled(true);
 }
 
 RadioButton::~RadioButton() = default;
diff --git a/ui/views/controls/combobox/combobox.cc b/ui/views/controls/combobox/combobox.cc
index e6938f3..b42ffa0 100644
--- a/ui/views/controls/combobox/combobox.cc
+++ b/ui/views/controls/combobox/combobox.cc
@@ -143,13 +143,8 @@
 
   UpdateBorder();
 
-  // The combobox uses the ink drop on the TransparentButton, but the focus ring
-  // needs to be set on the combobox itself. To ensure that the ink drop fills
-  // the entire bounds of the combobox including the portion of the combobox
-  // bounds that the focus ring paints over, we need to install the focus ring
-  // first so that the focus ring is added as a child before the
-  // TransparentButton and therefore painted before the ink drop.
   FocusRing::Install(this);
+  views::FocusRing::Get(this)->SetOutsetFocusRingDisabled(true);
 
   arrow_button_ =
       AddChildView(std::make_unique<TransparentButton>(base::BindRepeating(
diff --git a/ui/views/controls/editable_combobox/editable_combobox.cc b/ui/views/controls/editable_combobox/editable_combobox.cc
index dd11a329..111cbec 100644
--- a/ui/views/controls/editable_combobox/editable_combobox.cc
+++ b/ui/views/controls/editable_combobox/editable_combobox.cc
@@ -376,6 +376,7 @@
   textfield_->set_controller(this);
   textfield_->SetFontList(GetFontList());
   AddChildView(textfield_.get());
+  views::FocusRing::Get(textfield_)->SetOutsetFocusRingDisabled(true);
 
   control_elements_container_ = AddChildView(std::make_unique<BoxLayoutView>());
   if (features::IsChromeRefresh2023()) {
diff --git a/ui/views/controls/focus_ring.cc b/ui/views/controls/focus_ring.cc
index f22aa01..7f00d4a 100644
--- a/ui/views/controls/focus_ring.cc
+++ b/ui/views/controls/focus_ring.cc
@@ -172,6 +172,13 @@
   OnPropertyChanged(&halo_inset_, PropertyEffects::kPropertyEffectsPaint);
 }
 
+void FocusRing::SetOutsetFocusRingDisabled(bool disable) {
+  outset_focus_ring_disabled_ = disable;
+}
+bool FocusRing::GetOutsetFocusRingDisabled() const {
+  return outset_focus_ring_disabled_;
+}
+
 bool FocusRing::ShouldPaintForTesting() {
   return ShouldPaint();
 }
@@ -409,6 +416,7 @@
 ADD_PROPERTY_METADATA(absl::optional<ui::ColorId>, ColorId)
 ADD_PROPERTY_METADATA(float, HaloInset)
 ADD_PROPERTY_METADATA(float, HaloThickness)
+ADD_PROPERTY_METADATA(bool, OutsetFocusRingDisabled)
 END_METADATA
 
 }  // namespace views
diff --git a/ui/views/controls/focus_ring.h b/ui/views/controls/focus_ring.h
index 581afa5..50d3a09 100644
--- a/ui/views/controls/focus_ring.h
+++ b/ui/views/controls/focus_ring.h
@@ -90,8 +90,8 @@
 
   // Explicitly disable using style of focus ring that is drawn with a 2dp gap
   // between the focus ring and component.
-  void SetOutsetFocusRingDisabled() { outset_focus_ring_disabled_ = true; }
-  bool GetOutsetFocusRingDisabled() { return outset_focus_ring_disabled_; }
+  void SetOutsetFocusRingDisabled(bool disable);
+  bool GetOutsetFocusRingDisabled() const;
 
   bool ShouldPaintForTesting();
 
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc
index 726695b..2920ccd 100644
--- a/ui/views/controls/textfield/textfield.cc
+++ b/ui/views/controls/textfield/textfield.cc
@@ -242,7 +242,7 @@
   views::InstallRoundRectHighlightPathGenerator(this, gfx::Insets(),
                                                 GetCornerRadius());
   FocusRing::Install(this);
-  FocusRing::Get(this)->SetOutsetFocusRingDisabled();
+  FocusRing::Get(this)->SetOutsetFocusRingDisabled(true);
 
   if (::features::IsChromeRefresh2023()) {
     InkDrop::Install(this, std::make_unique<views::InkDropHost>(this));